SpringCloud Gateway 提供了基于Redis 和lua脚本实现的令牌桶算法进行限流,即 RequestRateLimiterGatewayFilterFactory类,通过设置过滤器实现限流。
1、maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
2、服务网关完整的配置文件如下
server: port: 8801 spring: application: name: gateway cloud: consul: host: localhost port: 8500 discovery: service-name: gateway gateway: discovery: locator: enabled: false lower-case-service-id: true routes: - id: logservice uri: lb://logservice predicates: - Path=/log/** filters: - StripPrefix=1 - id: orderservice uri: lb://orderservice predicates: - Path=/order/** - Method=GET filters: - StripPrefix=1 - name: RequestRateLimiter args: # #{@beanName} 限流key, bean对象名称,实现KeyResolver接口resolve方法的类对象。 key-resolver: "#{@urlKeyResolver}" # 令牌桶每秒填充10个令牌 redis-rate-limiter.replenishRate: 10 # 突发20个 redis-rate-limiter.burstCapacity: 50 # 每次请求消耗1个 redis-rate-limiter.requestedTokens: 1 redis: host: localhost port: 6379 database: 8 # 配置日志 logging: level: org.springframework.cloud.gateway: debug
3、KeyResolver 针对接口进行限流
@Component public class KeyResolverConfig { /** * 根据Url进行限流 */ @Bean public KeyResolver urlKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getURI().getPath()); } }
4、使用jmeter进行压测,20秒发送300个请求,get方式进行http请求,
http://localhost:8801/order/order
5、查看服务网关控制台日志里
成功转发的信息如下:
ratelimit.RedisRateLimiter : response: Response{allowed=true, headers={X-RateLimit-Remaining=23, X-RateLimit-Requested-Tokens=1, X-RateLimit-Burst-Capacity=50, X-RateLimit-Replenish-Rate=10}, tokensRemaining=-1}
失败的信息:
response: Response{allowed=false, headers={X-RateLimit-Remaining=0, X-RateLimit-Requested-Tokens=1, X-RateLimit-Burst-Capacity=50, X-RateLimit-Replenish-Rate=10}, tokensRemaining=-1}
失败的大约有60个。