Spring Cloud Hoxton 版本 gateway网关限流(自定义key支持多维度限流)
前言
本篇用来讲解–Spring Cloud Hoxton 版本 gateway网关路由!
摘要
- 我们可以在网关层面做限流的功能,防止高并发时把服务器搞崩,或者应对一些网络攻击等情况
- SpringCloudGateway为我们提供了一个很方便使用的令牌桶限流,思路:我们设置一个固定大小的令牌桶,如果令牌桶不满,则根据一定的频率向桶里放入令牌,每当有客户端的请求发来,会先从令牌桶里面取令牌,取到了则继续执行,取不到请求则会被拒绝,这样就达到了限流的作用,我们可以灵活地调整令牌补充速率和令牌桶大小,来细粒度的控制限流,我们使用redis来存储令牌,下面是一个简单的demo
(1)引入redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
(2)接下来自定义限流的维度,我们可以从域名、uri等维度进行限流
package com.cyj.gatewaycenter.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
/**
* @Description: 网关限流配置
* @BelongsProject: Family
* @BelongsPackage: com.cyj.gatewaycenter.config
* @Author: ChenYongJia
* @CreateTime: 2020-01-02 17:15
* @Email: chen87647213@163.com
* @Version: 1.0
*/
@Configuration
public class RedisRateLimiterConfig {
/**
* 根据路径去限流
* @return
*/
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));
}
/**
* 根据ip限流
* @return
*/
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
}
(3)接下来配置限流器的配置,将我们编写的解析器引用,并且配置令牌桶的属性,这里我配置的是,每秒补充一个令牌,令牌桶的大小为3,最后配置redis的参数,用起来非常简单
spring:
application:
#服务名称,随便写
name: gateway-center
cloud:
gateway:
discovery:
locator:
#开启从注册中心动态创建路由的功能
enabled: true
#使用小写服务名,默认是大写
lower-case-service-id: true
routes:
# 路由的ID
- id: path_route
# uri 代表路由的目标地址。注意:uri地址后面不要加 " / "
# 消息必须使用http进行转发,lb代表从注册中心获取服务
uri: lb://gateway-center # 可以直接跳转到具体的地址,如果要跳转到其他服务,则填写lb://<服务id>
predicates:
- Path=/gateway/** # 路由规则
filters:
- StripPrefix=1 # 不填则无法路由到其他服务
# - AddRequestHeader=X-Request-Foo, Bar
#- name: Hystrix # 添加熔断
#args:
#name: fallbackcmd
#fallbackUri: forward:/fallbacks # 熔断跳转地址
- name: RequestRateLimiter
args:
# 每秒允许处理的请求数量
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充平均速率
# 每秒最大处理的请求数量
redis-rate-limiter.burstCapacity: 3 # 令牌桶总容量
# 限流策略,对应策略的Bean
key-resolver: "#{@ipKeyResolver}"
redis:
host: 127.0.0.1
port: root
password: 123456
(4)配置好后,使用JMeter来压测一下接口,可以发现某些请求返回429错误码,被限流