Skip to content
广告❤️成为赞助商

介绍

主要功能 api 限流,短信,邮件 发送限流、控制恶意利用验证码功能 等。

安装依賴

  • Apache Maven
<dependency>
  <groupId>com.aizuda</groupId>
  <artifactId>aizuda-limiter</artifactId>
  <version>1.0.0</version>
</dependency>
  • Gradle DSL
implementation("com.aizuda:aizuda-limiter:1.0.0")

测试案例 aizuda-limiter-example

注意

  1. 该组件居于 Redis 分布式缓存实现。
  2. 表单重复提交也可以使用该组件,利用限流来解决。

限流

@RestController
public class TestController {

    /**
     * 限流
     * <p>
     * 测试多次访问观察浏览器及控制台输出日志
     * <p>
     * http://localhost:8080/test?name=abc
     */
    @GetMapping("/test")
    @RateLimit(
            // 唯一标示,支持SpEL表达式(可无),#name 为获取当前访问参数 name 内容
            key = "#name",
            // 限定阈值,时间间隔 interval 范围内超过该数量会触发锁
            count = 2,
            // 限制间隔时长(可无,默认 3 分钟)例如 5s 五秒,6m 六分钟,7h 七小时,8d 八天
            interval = "100s",
            // 策略(可无) ip 为获取当前访问IP地址(内置策略),自定义策略 user 为获取当前用户
            strategy = {IpKeyGenerateStrategy.TYPE, UserRateLimitStrategy.TYPE},
            // 提示消息(可无)
            message = "请勿频繁操作"
    )
    public String test(String name) {
        return "test" + name;
    }

}

分布式锁

public class LockTestController {
    private final LockTestComponent lockTestComponent;
    private final ApplicationContext applicationContext;
    private boolean alreadyReentrant;

    /**
     * 测试分布式锁的接口,建议多开几个实例测试、
     * 支持可重如
     * --server.port=8081
     *
     * @param name 参数
     * @return map
     */
    @GetMapping("/lock-reentrant")
    @DistributedLock(
            // 唯一标示,支持SpEL表达式(可无),'#name!=null?#name:'default'' 为获取当前访问参数 name 内容,如果为空,则默认为 'default'
            key = "#name!=null?#name:'default'",
            // 指定时间获取锁,如果在指定时间获取不到,则抛出对应异常,捕获此异常即可
            tryAcquireTimeout = "5s",
            acquireTimeoutMessage = "您请求的太快了"
    )
    public Map<String, Object> testLock(String name) {
        log.debug("Thread:{} execute first method", Thread.currentThread().getId());
        // 测试可重入
        LockTestController bean = applicationContext.getBean(LockTestController.class);
        if (!alreadyReentrant) {
            alreadyReentrant = true;
            bean.testLock(null);
            log.info("运行到这里,说明此锁是可重入的");
        }
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }

        return new HashMap<String, Object>(4) {{
            put("name", Optional.ofNullable(name).orElse("default string"));
        }};
    }

    /**
     * 测试获取分布式锁超时策略
     *
     * @param name 参数
     * @return map
     */
    @GetMapping("/failed-handler-test")
    @DistributedLock(
            // 唯一标示,支持SpEL表达式(可无),'#name!=null?#name:'default'' 为获取当前访问参数 name 内容,如果为空,则默认为 'default'
            key = "#name!=null?#name:'default'",
            // 指定时间获取锁,如果在指定时间获取不到,则抛出对应异常,捕获此异常即可
            tryAcquireTimeout = "5s"
    )
    public Map<String, Object> testFailedHandler(String name) {
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }

        return new HashMap<String, Object>(4) {{
            put("name", Optional.ofNullable(name).orElse("default string"));
        }};
    }

    /**
     * 测试监听器
     *
     * @param name 参数
     * @return map
     */
    @GetMapping("/lock-listener-test")
    @DistributedLock(
            // 唯一标示,支持SpEL表达式(可无),'#name!=null?#name:'default'' 为获取当前访问参数 name 内容,如果为空,则默认为 'default'
            key = "#name!=null?#name:'default'",
            // 指定时间获取锁,如果在指定时间获取不到,则抛出对应异常,捕获此异常即可
            tryAcquireTimeout = "5s"
    )
    public Map<String, Object> testLockListener(String name) {
        lockTestComponent.testLockListener(name);
        return new HashMap<String, Object>(4) {{
            put("name", Optional.ofNullable(name).orElse("default string"));
        }};
    }
}

注解说明

  • 速率限制注解 RateLimit
名称说明
key唯一标示,支持SpEL表达式
count限定阈值,时间间隔 interval 范围内超过该数量会触发锁
interval时间间隔,默认 3 分钟,例如 5s 五秒,6m 六分钟,7h 七小时,8d 八天
strategy限制策略
message提示消息,非必须
  • 分布式锁限制注解 DistributedLock
名称说明
key唯一标示,支持SpEL表达式
tryAcquireTimeout获取分布式锁超时失败时间,默认 10 秒,例如 5s 五秒,6m 六分钟,7h 七小时,8d 八天
strategy加key策略,需要实现 IKeyGenerateStrategy 接口注入到spring中
acquireTimeoutMessage获取分布式锁超时提示
useDefaultStrategy是否使用默认的key生成策略 DefaultKeyGenerateStrategy 作为前缀

每个人都是架构师