一、需求:
每个ip地址1秒内只能发送1次请求,多出来的请求返回429错误。
二、引入依赖
spring cloud gateway 默认使用redis的RateLimter限流算法来实现。所以我们要使用首先需要引入redis的依赖
<!--redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId><version>2.1.3.RELEASE</version>
</dependency>
三、定义KeyResolver
//定义一个KeyResolver@Beanpublic KeyResolver ipKeyResolver(){return new KeyResolver() {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {//获取访问者的ip地址, 通过访问者ip地址进行限流, 限流使用的是Redis中的令牌桶算法String hostString = exchange.getRequest().getRemoteAddress().getHostString();return Mono.just(hostString);}};}
四、application.yml
spring:application:name: sysgatewaycloud:gateway:globalcors:cors-configurations:'[/**]': # 匹配所有请求allowedOrigins: "*" #跨域处理 允许所有的域allowedMethods: # 支持的方法- GET- POST- PUT- DELETEroutes:#是指的两个服务- id: goodsuri: lb://goodspredicates:- Path=/goods/**filters:- StripPrefix= 1- name: RequestRateLimiter #请求数限流 名字不能随便写args:key-resolver: "#{@ipKeyResolver}"redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率redis-rate-limiter.burstCapacity: 1 #令牌桶总容量- id: systemuri: lb://systempredicates:- Path=/system/**filters:- StripPrefix= 1# 配置Redis 127.0.0.1可以省略配置redis:host: 192.168.200.128port: 6379
server:port: 9101
eureka:client:service-url:defaultZone: http://127.0.0.1:6868/eurekainstance:prefer-ip-address: true
- burstCapacity:令牌桶总容量。
- replenishRate:令牌桶每秒填充平均速率。
- key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。通过在replenishRate和中设置相同的值来实现稳定的速率burstCapacity。设置burstCapacity高于时,可以允许临时突发replenishRate。在这种情况下,需要在突发之间允许速率限制器一段时间(根据replenishRate),因为2次连续突发将导致请求被丢弃(HTTP 429 - Too Many Requests)key-resolver: "#{@userKeyResolver}" 用于通过SPEL表达式来指定使用哪一个KeyResolver.如上配置:表示 一秒内,允许 一个请求通过,令牌桶的填充速率也是一秒钟添加一个令牌。最大突发状况 也只允许 一秒内有一次请求,可以根据业务来调整 。