我是靠谱客的博主 友好母鸡,这篇文章主要介绍Spring Cloud Gateway 扩展支持动态限流,现在分享给大家,希望可以做个参考。

原生RequestRateLimiter 的不足
配置方式

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
spring: cloud: gateway: routes: - id: requestratelimiter_route uri: lb://pigx-upms order: 10000 predicates: - Path=/admin/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 1 redis-rate-limiter.burstCapacity: 3 key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean - StripPrefix=1

RequestRateLimiterGatewayFilterFactory

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public GatewayFilter apply(Config config) { KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver); RateLimiter<Object> limiter = getOrDefault(config.rateLimiter, defaultRateLimiter); boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey); HttpStatusHolder emptyKeyStatus = HttpStatusHolder .parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode)); return (exchange, chain) -> { return exchange.getResponse().setComplete(); }); }); }; }

实际生产过程中,必定不能满足我们的需求

生产中路由信息是保存数据库持久化或者配置中心,RequestRateLimiterGatewayFilterFactory 并不能随着持久化数据的改变而动态改变限流参数,不能做到实时根据流量来改变流量阈值

Sentinel Spring Cloud Gateway 流控支持
Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性,分布式系统的流量防卫兵。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组

pom 依赖

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<!--Spring Cloud Alibaba 封装的 sentinel 模块--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> <!--使用nacos 保存限流规则--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>

配置本地路由规则及其sentinel数据源

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
spring: application: name: sentinel-spring-cloud-gateway cloud: gateway: enabled: true discovery: locator: lower-case-service-id: true routes: - id: pigx_route uri: https://api.readhub.cn predicates: - Path=/topic/** sentinel: datasource.ds1.nacos: server-addr: 127.0.0.1:8848 data-id: gw-flow group-id: DEFAULT_GROUP ruleType: gw-api-group filter: enabled: true

配置nacos数据源中的限流策略
在这里插入图片描述
常用限流策略 常量

以客户端IP作为限流因子
public static final int PARAM_PARSE_STRATEGY_CLIENT_IP = 0;
以客户端HOST作为限流因子
public static final int PARAM_PARSE_STRATEGY_HOST = 1;
以客户端HEADER参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_HEADER = 2;
以客户端请求参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_URL_PARAM = 3;
以客户端请求Cookie作为限流因子
public static final int PARAM_PARSE_STRATEGY_COOKIE = 4;

核心源码解析 SentinelGatewayFilter
sentinel通过扩展Gateway的过滤器,通过选择的不同GatewayParamParser 过处理请求限流因子和数据源中的配置进行比较
源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); Mono<Void> asyncResult = chain.filter(exchange); if (route != null) { String routeId = route.getId(); Object[] params = paramParser.parseParameterFor(routeId, exchange, r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID); String origin = Optional.ofNullable(GatewayCallbackManager.getRequestOriginParser()) .map(f -> f.apply(exchange)) .orElse(""); asyncResult = asyncResult.transform( new SentinelReactorTransformer<>(new EntryConfig(routeId, EntryType.IN, 1, params, new ContextConfig(contextName(routeId), origin))) ); } Set<String> matchingApis = pickMatchingApiDefinitions(exchange); for (String apiName : matchingApis) { Object[] params = paramParser.parseParameterFor(apiName, exchange, r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME); asyncResult = asyncResult.transform( new SentinelReactorTransformer<>(new EntryConfig(apiName, EntryType.IN, 1, params)) ); } return asyncResult; }

效果演示
以上nacos 配置为 每秒只能通过5个请求,我们使用jmeter 4.0 来并发10个线程测试一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上图可以结果证明sentinel限流确实有效
动态修改限流参数
sentinel-datasource-nacos 作为sentinel的数据源,可以从如上 nacos 管理台实时刷新限流参数及其阈值
目前sentinel dashboard 1.6.2 暂未实现gateway 流控图形化控制 , 1.7.0会增加此功能

最后

以上就是友好母鸡最近收集整理的关于Spring Cloud Gateway 扩展支持动态限流的全部内容,更多相关Spring内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部