本篇文章为大家展示了Spring Cloud中怎么利用Gateway实现扩展支持动态限流,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
配置方式
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
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 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性,分布式系统的流量防卫兵。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流: route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
<!--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>
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
常用限流策略 常量
以客户端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
过处理请求限流因子和数据源中的配置进行比较 源码如下:
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实现扩展支持动态限流,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/giegie/blog/3080518