# limiter-spring-boot-starter **Repository Path**: tmq777/limiter-spring-boot-starter ## Basic Information - **Project Name**: limiter-spring-boot-starter - **Description**: 基于redis集群的令牌桶限流组件 - **Primary Language**: Java - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 1 - **Created**: 2022-03-09 - **Last Updated**: 2024-12-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, SpringBoot ## README # limiter-spring-boot-starter #### 介绍 基于redis集群的令牌桶限流组件 #### 开发环境 - jdk 11.0.10 - SpringBoot 2.6.2 - Idea #### 使用方法 1. 引入本jar包 ```xml cn.t.redis.limiter limiter-spring-boot-starter 1.0.0 ``` 2. 配置`Redis`连接信息 ```yaml spring: redis: #host: localhost # 单点连接ip #port: 18379 # # 单点连接端口 timeout: 6000 # 连接超时时间 password: your password client-type: lettuce #指定连接工厂类型 cluster: max-redirects: 3 # 获取失败 最大重定向次数 nodes: # 集群节点 - 127.0.0.1:7001 - 127.0.0.1:7002 - 127.0.0.1:7003 - 127.0.0.1:7004 - 127.0.0.1:7005 - 127.0.0.1:7006 lettuce: # lettuce连接池 pool: max-active: 100 # 连接池最大连接数(使用负值表示没有限制) max-idle: 20 # 最大空闲连接数 min-idle: 10 # 最小空闲连接数 max-wait: 1500 # 连接池最大阻塞等待时间(ms)(使用负值表示没有限制) ``` > stater中已经依赖了`spring-boot-starter-data-redis` > > 默认使用了`lettuce`,如果需要使用`jedis`,相关依赖也已经引入了。 其他依赖: ```xml org.springframework.boot spring-boot-starter-data-redis redis.clients jedis org.apache.commons commons-pool2 org.springframework.boot spring-boot-starter-aop ``` 自动配置类中默认配置了一个`RedisTemplate`, 如需要自定义则手动覆盖即可 ```java @Bean @ConditionalOnMissingBean(RedisTemplate.class) public RedisTemplate redisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(this.connectionFactory); // 定义Jackson2JsonRedisSerializer序列化对象 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 指定要序列化的域,ALL:field,get和set等,ANY: 可见性,会将有private修饰符的字段也序列化 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常 // objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 使用StringRedisSerializer来序列化和反序列化redis的key值 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // 使用jackson2JsonRedisSerializer序列化和反序列化value redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // 属性设置完成afterPropertiesSet就会被调用,可以对设置不成功的做一些默认处理 redisTemplate.afterPropertiesSet(); return redisTemplate; } ``` 3. 在需要限流的接口处使用注解 ```java @RequestMapping("/index") @RateLimit(interfaceName = "limit", maxPermits = 5, tokensPerSeconds = 1) public String ratelimit() { return "hello world"; } ``` > interfaceName: 接口名 > > maxPermits: 时间段内最大令牌数 > > tokensPerSeconds: 每秒恢复的令牌数 > > 以上配置指该接口同一时间内最大允许5个并发访问,令牌未满后,每秒恢复1个令牌,5秒后恢复完全,恢复过程中的最大并发量为当前时间点令牌桶中的剩余令牌数量 4. 未通过限流的访问会抛出异常,建议在全局异常处理器中捕获处理。 例如: ```java @RestControllerAdvice public class GlobalErrorController { @ExceptionHandler(RateLimitException.class) public String ratelimiteHanler(RateLimitException e) { return e.getMessage(); } } ```