sentinel整合nacos在gateway中实现限流
一、应用层面完成网关整合nacos和sentinel实现限流
前沿
启动nacos与sentinel的jar的启动,这里不细讲
sentinel官网
https://github.com/alibaba/Sentinel/wiki/主页
sentinel 下载地址
https://github.com/alibaba/Sentinel/releases
nacos官网
https://nacos.io/zh-cn/docs/deployment.html
nacos下载地址
https://github.com/alibaba/nacos/releases
1.1 导报
在gateway中导入所需的jar
xml
<!--网关限流3组件-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
集成nacos的注册中心与配置中心
xml
<!--注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!--配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
1.2 配置文件(仅展示整合sentinel部分)
yaml
# 应用名称
spring:
cloud:
sentinel:
transport:
# sentinel的连接地址
dashboard: localhost:7777
# sentinel与服务的通信端口,只要不冲突就行
port: 8720
# 取消控制台懒加载
eager: true
# 获取sentinel配置在nacos的文件信息
datasource:
ds1:
nacos:
# nacos的地址
server-addr: ${spring.cloud.nacos.discovery.server-addr}
# nacos的文件名称
data-id: gateway-flow-rule-sentinel
# 在nacos的命名空间 注意public空间下不能设置为public否则获取不到配置,如果在public就不写此行
namespace: 49dc14c4-e3a6-48de-a773-6fdda300424f
# 分组名称
group-id: DEFAULT_GROUP
# 文件类型
data-type: json
# 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType
# FlowRule 就是限流规则
rule-type: gw-flow
ds2:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
data-id: gateway-flow-rule-api-sentinel
namespace: 49dc14c4-e3a6-48de-a773-6fdda300424f # 注意public空间下不能显示的设置为public否则获取不到配置
group-id: DEFAULT_GROUP
data-type: json
# 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType
# FlowRule 就是限流规则
rule-type: gw-api-group
1.3 编写配置类
java
@Slf4j
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// Register the block exception handler for Spring Cloud Gateway.
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
}
1.4 编写返回自定义限流拦截信息(如果不写此类返回就是429)
java
@Configuration
public class SentinelGatewayConfig {
public SentinelGatewayConfig() {
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
R error = R.error(500, "限流啦 别在试啦");
String errorStr = JSON.toJSONString(error);
Mono<ServerResponse> just = ServerResponse.ok().body(Mono.just(errorStr), String.class);
return just;
}
});
}
}
注:
如果启动后sentinel的画面没有API菜单,那就在启动类main函数里加上
java
// 添加此代码,在Sentinel控制台中做判断使用
System.setProperty("csp.sentinel.app.type", "1");
1.5 限流json文件
文件位置
gateway-flow-rule-sentinel的配置内容
yaml
[
{
"resource": "macro-member",
"resourceMode": 0,
"count": 1,
"intervalSec": 60
},
{
"resource": "macro-member-api",
"resourceMode": 1,
"count": 2,
"intervalSec": 60
}
]
gateway-flow-rule-api-sentinel
yaml
[{
"apiName": "macro-member-api",
"predicateItems": [
{
"pattern": "/api/member/sysUser/getUsers"
},
{
"pattern": "/imooc/ecommerce-nacos-client/**",
"matchStrategy": 1
},
{
"pattern": "/api/member/sysUser/getUserByName"
}
]
}]
1.6 测试
访问效果是达到了限流的目的
nacos的限流规则更改,sentinel控制台能马上感应到
二、sentinel限流原理
Sentinel中的令牌桶算法采用固定窗口算法,将时间窗口分成若干个固定长度的小窗口,并在每个小窗口开始时向令牌桶中添加一定数量的令牌。每次请求需要获取一个令牌才能执行,如果令牌桶中的令牌数量不足,则请求将被拒绝。通过调整每个小窗口的长度和每次添加的令牌数量,可以控制限流的速率
配置参数的含义
FIELD | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 限流阈值 | |
grade | 限流阈值类型,QPS 模式(1)或并发线程数模式(0) | QPS 模式 |
limitApp | 流控针对的调用来源 | default,代表不区分调用来源 |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流 | 直接拒绝 |
resource | 资源名,资源名是限流规则的作用对象 | 直接拒绝 |
resourceMode | 限流方式 0-服务限流 1-分组限流 | |
intervalSec | 统计时间窗口,单位是秒 | 1 |
matchStrategy | 参数值的匹配策略目前支持精确匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正则匹配(PARAM_MATCH_STRATEGY_REGEX) |