目录
-
- 一、前言
- 二、版本选择和适配
-
- 2.1、本文使用各组件版本
- 2.2、官方推荐版本
- 2.1、本文使用各组件版本
- 三、部署sentinel-dashboard
-
- 3.1、下载 sentinel-dashboard jar包
- 3.2、启动 sentinel-dashboard
- 3.1、下载 sentinel-dashboard jar包
- 四、Gateway 集成 Sentinel实现控制台配置流控规则测试
-
- 4.1、添加Gateway 集成 Sentinel 包
- 4.2、添加 Gateway 服务启动JVM参数
-
- 4.2.1、配置说明
* 4.2.2、启动说明
* * 4.2.2.1、使用 jar 包启动Gateway添加JVM启动参数
* 4.2.2.2、IDEA中配置JVM启动参数(IDEA版本2022.2.1)
- 4.2.1、配置说明
- 4.3、启动 Gateway 注册到 Sentinel-dashboard 实现接口流控规则动态配置
-
- 4.3.1、启动 Gateway 注册到 Sentinel-dashboard
* 4.3.2、通过 Sentinel-dashboard 配置指定接口限流
- 4.3.1、启动 Gateway 注册到 Sentinel-dashboard
- 4.4、注意事项
- 4.1、添加Gateway 集成 Sentinel 包
- 五、Gateway 集成 Sentinel 常用配置
-
- 5.1、热加载
- 5.2、降级处理配置(这里提供代码配置和使用配置文件配置)
-
- 5.2.1、通过代码配置(配置文件配置比代码配置优先级高)
* 5.2.2、通过配置文件配置
- 5.2.1、通过代码配置(配置文件配置比代码配置优先级高)
- 5.1、热加载
- 六、自定义本地加载流控规则
-
- 6.1、通过代码加载流控规则
- 6.2、通过本地配置文件加载流控规则
-
- 6.2.1、API分组规则json文件编写(gateway-sentinel-api-groups.json)
* 6.2.2、流控规则json文件编写(gateway-sentinel-flow-rules.json)
* 6.2.3、配置文件配置加载API分组和流控规则json文件
- 6.2.1、API分组规则json文件编写(gateway-sentinel-api-groups.json)
- 6.1、通过代码加载流控规则
- 七、动态监听Nacos规则配置实时更新流控规则实现(推荐)
-
- 7.1、添加sentinel集成nacos包
- 7.2、Nacos配置中心添加API分组规则json(gateway-sentinel-api-groups)
- 7.3、Nacos配置中心添加流控规则json(gateway-sentinel-flow-rules)
- 7.4、配置文件配置加载Nacos配置中心API分组和流控规则json
- 7.5、测试效果
- 7.1、添加sentinel集成nacos包
一、前言
Sentinel 是 SpringCloud Alibaba 家族的服务保护组件,很多项目在前中期没有遇到流量突增不太注意服务保护的重要性,当流量突增打爆应用服务或数据库时束手无策,可以不配置流控规则,但是需要时一定可以热加载使用,本文会对集成Sentinel以及动态拉取Nacos配置规则实现热加载流控规则进行讲解。
二、版本选择和适配
使用 SpringCloud Alibaba 家族组件,要注意一下版本兼容问题,避免出现一些奇怪的问题,这里会说明本文使用的各组件版本,以及 SpringCloud Alibaba 推荐的各版本适配。
2.1、本文使用各组件版本
部分组件对版本兼容要求其实没有那么高,比如Nacos,不一定要按照官方推荐版本,差几个小版本没有什么影响,我本地使用的一直是Nacos2.0.2,代码集成实现基本都一样。
JDK:1.8.0
Spring-Boot:2.3.12.RELEASE
Spring-Cloud:Hoxton.SR12
Spring-Cloud-Alibaba:2.2.9.RELEASE
Nacos:2.0.2
Sentinel:1.8.5
2.2、官方推荐版本
三、部署sentinel-dashboard
3.1、下载 sentinel-dashboard jar包
这里使用sentinel-dashboard-1.8.5,这里提供两个下载地址,需要其它版本可以自行去github下载。
github下载地址
百度网盘地址

3.2、启动 sentinel-dashboard
1java -Dserver.port=8180 -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar 2
- -Dserver.port=8180
sentine 服务控制台端口 - -Dsentinel.dashboard.auth.username=sentinel
sentine 控制台登录账号,不设置默认sentinel - -Dsentinel.dashboard.auth.password=123456
sentine 控制台登录密码,不设置默认sentinel - -Dcsp.sentinel.dashboard.server=localhost:8180
将控制台自身注册到server - -Dproject.name=sentinel-dashboard
控制台服务自己项目名称


四、Gateway 集成 Sentinel实现控制台配置流控规则测试
4.1、添加Gateway 集成 Sentinel 包
在原有网关项目基础上添加上这两个包,这两个包会将gateway集成sentinel,并且默认是自动配置的,无需手动配置。
1 <dependency> 2 <groupId>com.alibaba.cloud</groupId> 3 <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>com.alibaba.cloud</groupId> 7 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> 8 </dependency> 9
4.2、添加 Gateway 服务启动JVM参数
4.2.1、配置说明
Gateway 连接 Sentinel 控制台的配置,Sentinel1.7.0 版本以下不支持配置文件配置,推荐直接使用JVM参数配置。
- 添加JVM启动参数:
-Dcsp.sentinel.dashboard.server=127.0.0.1:8180
-Dcsp.sentinel.api.port=18719
-Dproject.name=kerwin-gateway
-Dcsp.sentinel.app.type=1 - 参数说明:
-Dcsp.sentinel.dashboard.server:指定控制台地址和端口。
-Dproject.name:在sentinel控制台中展示的项目名称。
-Dcsp.sentinel.api.port:指定客户端监控 API 的端口(默认是 8719),如控制台修改规则,则会向该端口推送规则信息。
-Dcsp.sentinel.app.type:从 1.6.3 版本开始,控制台支持网关流控规则管理。该启动参数设置成1会将您的服务标记为 API Gateway,在接入控制台时您的服务会自动注册为网关类型,然后您即可在控制台配置网关规则和 API 分组。
4.2.2、启动说明
这里提供服务打成jar包启动和使用IDEA开发工具添加JVM参数启动示例。
4.2.2.1、使用 jar 包启动Gateway添加JVM启动参数
1java -Dcsp.sentinel.dashboard.server=127.0.0.1:8180 -Dcsp.sentinel.api.port=18719 -Dproject.name=kerwin-gateway -Dcsp.sentinel.app.type=1 -jar kerwin-gateway.jar 2
4.2.2.2、IDEA中配置JVM启动参数(IDEA版本2022.2.1)
不同版本IDEA可以配置入口不同,有需要可以自己查询



4.3、启动 Gateway 注册到 Sentinel-dashboard 实现接口流控规则动态配置
这里需要注意,Gateway 集成 Sentinel-dashboard 默认是懒加载的,需要调用一次接口才能注册到 Sentinel-dashboard,也可以直接在 Gateway 中配置成热加载,添加spring.cloud.sentinel.eager:true实现服务器启动了自动心跳注册。
4.3.1、启动 Gateway 注册到 Sentinel-dashboard

4.3.2、通过 Sentinel-dashboard 配置指定接口限流
这里需要注意,这个流控规则是按照组级别来的,一个组内所有匹配规则会共用一个阈值,如果需要在网关应用配置单独接口流控规则目前来看只能配置多个分组,然后单独配置规则。
- 1、新增 API 分组

- 2、自定义分组内 API 匹配规则

- 3、新增网关流控规则

- 4、配置网关流控规则(这里需要注意,这个流控规则是按照组级别来的,一个组内所有匹配规则共用一个阈值)

- 5、测试限流规则
快速请求两次可以看到服务端响应Blocked by Sentinel: ParamFlowException,响应内容也是可以自定义的,这个会在后面说明。

PS:1秒内同时请求一次 /user/info 接口 和 /user/list 接口,也会响应Blocked by Sentinel: ParamFlowException,因为同一个分组共用一个阈值,如果要单独配置某一个接口目前看只能整多个分组。
4.4、注意事项
需要注意:如果不做特殊处理,通过Sentinel控制台配置的规则在应用服务重启后就没了,通过Sentinel控制台配置流控规则的本质其实就是将编辑好的规则加载到应用服务缓存中,并不会进行持久化,如果想要持久化Sentinel控制台配置的规则需要特殊处理,后续会进行说明。
五、Gateway 集成 Sentinel 常用配置
5.1、热加载
1spring: 2 cloud: 3 sentinel: 4 # 设置sentinel为热加载 默认为false 5 eager: true 6
5.2、降级处理配置(这里提供代码配置和使用配置文件配置)
5.2.1、通过代码配置(配置文件配置比代码配置优先级高)
1import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; 2import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager; 3import org.springframework.context.annotation.Configuration; 4import org.springframework.http.HttpStatus; 5import org.springframework.http.MediaType; 6import org.springframework.web.reactive.function.server.ServerResponse; 7import org.springframework.web.server.ServerWebExchange; 8import reactor.core.publisher.Mono; 9 10import javax.annotation.PostConstruct; 11 12@Configuration 13public class SentinelGatewayConfiguration { 14 15 /** 16 * 自定义降级处理响应 17 */ 18 @PostConstruct 19 public void init(){ 20 GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() { 21 @Override 22 public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) { 23 return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).bodyValue("{"code":500,"msg":"代码配置-被限流了!"}"); 24 } 25 }); 26 } 27} 28

5.2.2、通过配置文件配置
1spring: 2 cloud: 3 sentinel: 4 # 设置sentinel为热加载 默认为false 5 eager: true 6 scg: 7 # 降级处理配置 也可以在代码中实现 8 fallback: 9 # 指定降级处理的模式为返回响应,也可以配置成重定向redirect,配置重定向需要指定重定向地址 10 mode: 'response' 11 response-status: 200 12 response-body: '{"code":500,"msg":"配置文件配置-被限流了!"}' 13 # mode 为 redirect 时使用 14 redirect: 'https://blog.csdn.net/weixin_44606481' 15

六、自定义本地加载流控规则
因为 sentinel-dashboard 不会持久化手动配置的流控规则,一般情况下我们都会提前配置一些我们需要的规则,可以通过代码或者配置文件配置。
6.1、通过代码加载流控规则
Sentinel 的API管理存储在 GatewayApiDefinitionManager 类中,流控规则存储在 GatewayRuleManager 类中,添加好自己需要的配置即可。
1import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants; 2import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; 3import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem; 4import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem; 5import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager; 6import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; 7import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; 8import org.springframework.context.annotation.Configuration; 9 10import javax.annotation.PostConstruct; 11import java.util.HashSet; 12import java.util.Set; 13 14@Configuration 15public class SentinelGatewayRuleConfiguration { 16 17 @PostConstruct 18 public void initRule(){ 19 // 加载根据路由 ID 配置限流规则 20 this.initGatewayFlowRules(); 21 // 加载根据API分组配置限流规则 22 this.initApiDefinitions(); 23 } 24 25 private void initGatewayFlowRules() { 26 // 存储限流规则的集合 27 Set<GatewayFlowRule> rules = GatewayRuleManager.getRules(); 28 if(rules == null){ 29 rules = new HashSet<>(); 30 } 31 // 根据路由 ID 配置限流规则 32 GatewayFlowRule rule1 = new GatewayFlowRule("kerwin-user") 33 .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID) 34 .setCount(1) // QPS阈值 35 .setIntervalSec(1); // 间隔 36 rules.add(rule1); 37 // 加载限流规则 38 GatewayRuleManager.loadRules(rules); 39 } 40 41 private void initApiDefinitions() { 42 Set<ApiDefinition> apiDefinitions = GatewayApiDefinitionManager.getApiDefinitions(); 43 if(apiDefinitions == null){ 44 apiDefinitions = new HashSet<>(); 45 } 46 // 创建一个 API 分组 47 ApiDefinition apiDefinition1 = new ApiDefinition("user服务API组"); 48 // API 分组 URL 匹配规则 49 Set<ApiPredicateItem> apiPathPredicateItems = new HashSet<>(); 50 // 添加精确匹配 匹配为 /api-user/user/info 的url 51 apiPathPredicateItems.add(new ApiPathPredicateItem().setPattern("/api-user/user/info") 52 .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_EXACT)); 53 // 添加前缀匹配 用于匹配以 /api-user/user 开头的URL 54 apiPathPredicateItems.add(new ApiPathPredicateItem().setPattern("/api-user/user/**") 55 .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); 56// // 添加正则匹配 用于匹配以 list 结尾的 URL 57// apiPathPredicateItems.add(new ApiPathPredicateItem().setPattern("^.*list$") 58// .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_REGEX)); 59 60 apiDefinition1.setPredicateItems(apiPathPredicateItems); 61 apiDefinitions.add(apiDefinition1); 62 63 // 根据 API 分组配置限流规则 64 Set<GatewayFlowRule> rules = GatewayRuleManager.getRules(); 65 if(rules == null){ 66 rules = new HashSet<>(); 67 } 68 GatewayFlowRule rule1 = new GatewayFlowRule(apiDefinition1.getApiName()) 69 .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME) 70 .setCount(1) // QPS阈值 71 .setIntervalSec(1); // 间隔 72 rules.add(rule1); 73 74 // 加载 API 分组定义 75 GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions); 76 // 加载限流规则 77 GatewayRuleManager.loadRules(rules); 78 } 79} 80
项目启动后可以在Sentinel控制台看到代码配置的API分组和流控规则。
6.2、通过本地配置文件加载流控规则
通过代码手动配置会比较麻烦而且不易调整,Gateway集成Sentinel包提供了通过配置文件加载API分组和流控规则实现,这里会将API分组和流控规则都分别写入不同的json文件中,交由对于实现类去进行加载。
6.2.1、API分组规则json文件编写(gateway-sentinel-api-groups.json)
在resource目录创建gateway-sentinel-api-groups.json将API分组规则内容填进去。
1[ 2 { 3 "apiName": "user服务API组", 4 "predicateItems": [ 5 { 6 "pattern": "/api-user/user/info", 7 "matchStrategy": 0 8 }, 9 { 10 "pattern": "/api-user/user/**", 11 "matchStrategy": 1 12 } 13 ] 14 } 15] 16
解释:
- apiName:
字符串,代表 API 组名称,这里是 “user服务API组”,用于统一管理相关 API。 - predicateItems:
数组,包含多个 predicateItem 对象,用于描述 API 的匹配模式。 - predicateItem 内部元素:
- pattern:
字符串,使用不同风格的表达式。
例如,“/api-user/user/info” 精确匹配该路径;“/api-user/user/**” 匹配 /api-user/user/ 下的所有路径(包括子路径)。 - matchStrategy:
整数,匹配策略:
0:精确匹配,路径需与 pattern 完全一致。
1:前缀匹配,路径以 pattern 开头即可。
2:正则匹配,使用 pattern 作为正则表达式进行匹配。
- pattern:
6.2.2、流控规则json文件编写(gateway-sentinel-flow-rules.json)
在resource目录创建gateway-sentinel-flow-rules.json将流控规则内容填进去。
1[ 2 { 3 "resource": "user服务API组", 4 "resourceMode": 1, 5 "count": 1, 6 "intervalSec": 1, 7 "burst": 0, 8 "paramItem": null, 9 "controlBehavior": 0, 10 "maxQueueingTimeoutMs": 0 11 }, 12 { 13 "resource": "kerwin-user", 14 "resourceMode": 0, 15 "count": 1, 16 "intervalSec": 1, 17 "burst": 0, 18 "paramItem": null, 19 "controlBehavior": 0, 20 "maxQueueingTimeoutMs": 0 21 } 22] 23
字段解释:
- resource:资源名称,用于标识要进行流控的目标。可以是路由 ID、自定义 API 分组名称等。在网关场景中,资源可以代表一个具体的路由或者一组路由的集合。
- resourceMode:
- 0:代表资源模式,对应 SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID,表示基于 Route ID 进行资源匹配。
- 1:API分组模式,对应 SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME,标识基于API分组进行资源匹配。
- count:流控阈值,根据 grade 字段的不同,其代表的意义也不同。如果 grade 为 QPS 限流,count 表示每秒允许通过的请求数量;如果 grade 为并发线程数限流,count 表示允许的最大并发线程数。
- grade:流控阈值类型,取值有两种。1 表示 QPS(每秒查询率)限流,0 表示并发线程数限流。
- intervalSec:统计时间窗口,单位为秒。表示在多长时间内统计请求数量以判断是否触发流控。
- controlBehavior:流控效果,即当请求超过阈值时的处理方式
- 0:快速失败,请求超过阈值时直接拒绝并抛出异常
- 2:匀速排队,请求会进入队列,按照固定速率处理,避免流量突发
- burst:仅在 controlBehavior 为 0(快速失败)时有效,表示突发流量容忍值。在短时间内允许超过阈值的额外请求数量,用于应对突发流量场景。
- maxQueueingTimeoutMs:仅在 controlBehavior 为 2(匀速排队)时有效,表示请求在队列中的最大排队时间,单位为毫秒。超过该时间的请求将被拒绝。
6.2.3、配置文件配置加载API分组和流控规则json文件
在配置文件中添加API分组和流控规则读取数据源配置,这里省略了其它Sentinel配置需要可以看之前配置内容添加。
1spring: 2 cloud: 3 sentinel: 4 # 设置sentinel为热加载 默认为false 5 eager: true 6 # API分组&流控规则配置文件配置 7 datasource: 8 ds1: 9 file: 10 file: classpath:gateway-sentinel-api-groups.json 11 ruleType: gw-api-group # 网关API分组 12 dataType: json 13 ds2: 14 file: 15 file: classpath:gateway-sentinel-flow-rules.json 16 ruleType: gw-flow # 网关流控规则 17 dataType: json 18
这里就不贴图了,配置完成后启动看看Sentinel控制台是否有初始化这些配置,要记得开启热加载。
七、动态监听Nacos规则配置实时更新流控规则实现(推荐)
通过Nacos配置中心动态拉取加载流控规则和本地配置文件配置是类似的,编写的规则json是一样的,只是需要指定一下加载的数据源为Nacos读取,并且已经实现了动态加载,在Nacos配置中心修改规则会进行实时同步。
7.1、添加sentinel集成nacos包
sentinel读取nacos配置需要添加这个适配包。
1 <dependency> 2 <groupId>com.alibaba.csp</groupId> 3 <artifactId>sentinel-datasource-nacos</artifactId> 4 </dependency> 5
7.2、Nacos配置中心添加API分组规则json(gateway-sentinel-api-groups)
配置的内容和本文6.2.1中一致。

7.3、Nacos配置中心添加流控规则json(gateway-sentinel-flow-rules)
配置的内容和本文6.2.2中一致。

7.4、配置文件配置加载Nacos配置中心API分组和流控规则json
1spring: 2 cloud: 3 sentinel: 4 # 设置sentinel为热加载 默认为false 5 eager: true 6 # API分组&流控规则配置文件配置 7 datasource: 8 ds1: 9 nacos: 10 server-addr: 172.16.8.169:8848 11 data-id: gateway-sentinel-api-groups 12 namespace: springcloud-component-example 13 group-id: DEFAULT_GROUP 14 username: nacos 15 password: nacos 16 data-type: json 17 rule-type: gw-api-group 18 ds2: 19 nacos: 20 server-addr: 172.16.8.169:8848 21 data-id: gateway-sentinel-flow-rules 22 namespace: springcloud-component-example 23 group-id: DEFAULT_GROUP 24 username: nacos 25 password: nacos 26 data-type: json 27 rule-type: gw-flow 28
7.5、测试效果
- 1、启动网关服务,查看注册API分组和流控规则

- 2、Nacos配置中心修改流控规则

- 3、查看sentinel控制台同步情况

《SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则》 是转载文章,点击查看原文。
