1、简介
在线文档:
https://sentinelguard.io/zh-cn/docs/system-adaptive-protection.html
功能:
- 流量控制
- 速率控制
- 熔断和限流
和Hystrix的区别:
-
Hystrix需要手动搭建监控平台
(Dashboard:对Hystrix进行图形化的监控)
-
没有web界面配置
2、快速开始
注:不能将Sentinel部署在云服务器上,因为下面的quickstart需要sentinel访问项目的ip,外网无法访问内网ip,所以我推荐你使用widnows的docker来完成下面的操作。
①安装启动
启动Nacos:
docker run --name nacos-standalone -e MODE=standalone -e JVM_XMS=256m -e JVM_XMX=256m -e JVM_XMN=128m -p 8848:8848 -d nacos/nacos-server
安装启动Sentinel:
#拉取sentinel镜像
docker pull bladex/sentinel-dashboard
#运行sentinel(docker里的sentinel是8858端口)
docker run --name sentinel -d -p 8858:8858 bladex/sentinel-dashboard
进入控制台:
②Server工程
1.新建模块cloudalibaba-sentinel-service8401
2.依赖:
<dependencies>
<!-- SpringCloud ailibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- SpringCloud ailibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.yml:
经过我个人的测试,docker下cleint-ip设置为localhost或者127.0.0.1都会出现监控和dashboard完全相同的问题,查看网络的局域网ip填写可以正常显示
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinal-service
cloud:
nacos:
discovery:
#Nacos服务注册中心地址(改成自己的服务器ip地址,本地用localhost)
#server-addr: 101.43.244.40:8848
server-addr: localhost:8848
sentinel:
transport:
#配置Sentin dashboard地址(改成自己的服务器ip地址,本地用localhost)
dashboard: localhost:8858
client-ip: 192.168.31.30
#client-ip: 127.0.0.1
# 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
port: 8719
management:
endpoints:
web:
exposure:
include: '*'
4.启动类:
@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401 {
public static void main(String[] args) {
SpringApplication.run(MainApp8401.class, args);
}
}
5.Controller:
@RestController
public class FlowLimitController {
@GetMapping("/testA")
public String testA() {
return "----testA";
}
@GetMapping("/testB")
public String testB() {
return "----testB";
}
}
6.启动:
访问testA和testB接口
查看sentinel控制台:
3、流控规则
流量控制(flow control)其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
①新建流控规则
1.在流控规则处创建
2.在簇点链路中创建
流控效果检查:
②阈值类型
QPS:每秒的请求数
线程数:调用该API的并发线程数
③流控模式
一.直接
对该资源进行限流
二.关联
使用关联模式,当关联资源/testB
达到了阈值1,testA
也会被限流。
删除testB的直接模式的限流,只保留关联模式限流:
因为关联模式只会对testA限流,不对testB限流,如果保留testB限流QPS条件,那么关联模式限流的阈值无法达到。
使用Jmeter测试:
启动Jmeter压测,访问testA接口,此时testA被限流,关联模式测试完成:
三.链路
只针对指定的链路进行统计限流
比如testA,testB,都调用childTest接口,所以存在两条链路testA->childTest和testB->childTest。
假如我只想对testA->childTest这条链路进行限流:
注意:
Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解去配置文件里配置,关闭context,就可以让controller里的方法单独成为一个链路;不关闭context的话,controller里的方法都会默认进去sentinel默认的根链路里,这样就只有一条链路,无法流控链路模式,如下图所示:
service.TestService:
@Service
public class TestService {
@SentinelResource("childTest")
public String childTest(){
return "child";
}
}
修改Controller:
@RestController
public class FlowLimitController {
@Resource
private TestService testService;
@GetMapping("/testA")
public String testA() {
return "----testA"+testService.childTest();
}
@GetMapping("/testB")
public String testB() {
return "----testB"+testService.childTest();
}
}
修改yml,关闭context(没有提示):、
这里存在问题:1.6.3-1.7.0之间的Sentinel,此注释无效
从1.6.3 版本开始,Sentinel Web filter 默认收敛所有URL的入口 context,因此链路限流不生效。
1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在 CommonFilter 引入了WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。
解决办法:
修改Springcloud alibaba的版本号:
如果无法识别注释,为上述问题,需要解决。
启动,如下图所示,即为关闭了context收敛:
配置链路模式流量控制,对于childTest的testA入口进行流量限制:
对testA入口进行压测:
结果如下:
childTest对于testB入口无流量限制,而对于testA入口存在流量限制:
④流控效果
一.快速失败
直接失败,抛出异常
二.预热
应用场景:系统刚开启,秒杀等
公式:阈值/coldFacotr(默认为3)
默认冷加载因子为3,即请求QPS从threshold/3开始,经过预热时长逐渐升到设定的限流,冷启动
例:
设置预热,阈值为6,最初的阈值为6/3=2,经过10s升到6
三.排队等待
不同于快速失败,超过QPS的会等待,设置一个超时时间,如果在时间内没有被处理,会抛出异常。
4、降级规则
Sentinel现已支持半开状态
①慢调用比例
慢调用比例 (SLOW_REQUEST_RATIO
):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
1.在Controller上添加方法:
设置休眠为1s
@GetMapping("/testC")
public String testC() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("testC 测试RT");
return "----testC";
}
2.设置Sentinel降级为慢比例调用
Jmeter测试:
后面如果服务正常,可以进行半开测试,如果下一次请求小于最大响应时间,服务熔断恢复
②异常比例
异常比例 (ERROR_RATIO
):当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]
,代表 0% - 100%。
Controller添加异常模拟方法:
@GetMapping("/testD")
public String testD() throws Exception {
double random = (int)(Math.random()*10);
if (random==0) throw new Exception("异常模拟");
log.info("testD 测试比例异常");
return "----testD";
}
设置Sentinel服务降级为异常比例:
测试:
使用Jmeter进行测试,当到达异常比例,进入熔断状态,5s后使用浏览器调用接口,进入半开状态,此时使用浏览器调用接口,接口返回正常,断路器从半开状态进行关闭状态。
③异常数
异常数 (ERROR_COUNT
):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
使用②中Controller的方法,Sentinel配置:
同②的测试,当异常数达到了一定值,进入熔断状态,5s后使用浏览器调用接口,进入半开状态,此时使用浏览器调用接口,接口返回正常,断路器从半开状态进行关闭状态。
5、热点规则
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。
热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
在前面的Hystrix中,当降级时会有fallbcak方法,在Sentinel同样存在这样的兜底方法定义方式:@SentinelResource
①使用blockHandler
1.依赖(默认包含):
2.Controller添加方法:
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey", blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1", required = false)String p1,
@RequestParam(value = "p2", required = false)String p2) {
return "----testHotKey";
}
//兜底方法
public String deal_testHotKey(String p1, String p2, BlockException exception) {
// sentinel的默认提示都是: Blocked by Sentinel (flow limiting)
return "----deal_testHotKey, o(╥﹏╥)o";
}
Sentinel设置:
②不使用blockHandler
不使用blockHandler,当达到阈值,进入窗口时,会直接跑出异常,返回500错误
③参数例外项
在上面的热点规则设置中,当对应参数QPS达到一定阈值后就会被限流。对参数进行特定例外项设置,特定参数具有特地的QPS限制:
Jmeter测试:
发起50个请求,p1=5,前40个请求正常处理,最后的10个请求出错:
④blockHanlder与异常
不同于Hystrix的fallback,blockHandler不会自动对异常进行兜底方法处理,如果方法出错,而未满足Sentinel的控制台设置,会返回500错误
@SentinelResouce:
处理的是Sentinel控制台配置的违规情况,使用blockHandler进行兜底处理
6、系统规则
个人理解为:对整个应用的入口的流量的控制
系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN
),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。
系统规则支持以下的模式:
- Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的
maxQps * minRt
估算得出。设定参考值一般是CPU cores * 2.5
。 - CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
- 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
对入口QPS进行限制测试:
仅做测试,实际测试和效果不对应:
如下,QPS阈值引起的限流
7、@SentinelResource
前置操作:
8401引入commons依赖
<dependency>
<groupId>cn.zko0.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
新建一个RateLimitController
@RestController
public class RateLimitController {
}
①按资源名称限流
@GetMapping("/byResource")
@SentinelResource(value = "byResource",blockHandler = "handleException")
public CommonResult byResource() {
return new CommonResult(200,"按照资源名称限流测试",new Payment(2020L,"serial001"));
}
//兜底方法
public CommonResult handleException(BlockException exception) {
return new CommonResult(444,exception.getClass().getCanonicalName() + "\t 服务不可用");
}
在Sentinel中进行配置限制
测试,成功:
QPS超过1,会使用blockHandler方法
②按照URL地址限流
在Controller中添加接口:
@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl") //没有兜底方法,系统就用默认的
public CommonResult byUrl() {
return new CommonResult(200,"按照byUrl限流测试",new Payment(2020L,"serial002"));
}
在Sentinel中设置:
测试:
③blockHandler问题解决
blockHandler问题:
- 系统默认,不能体现业务
- 自定义方法和业务代码耦合在一起
- 每个代码都需要兜底方法,代码膨胀
- 没有全局的统一处理
解决:
自定义blockHandler类
public class CustomerBlockHandler {
public static CommonResult handlerException(BlockException exception) {
return new CommonResult(444,"按照客户自定义限流测试,Glogal handlerException ---- 1");
}
public static CommonResult handlerException2(BlockException exception) {
return new CommonResult(444,"按照客户自定义限流测试,Glogal handlerException ---- 2");
}
}
使用blockHandlerClass
和blockHandler
对兜底方法和业务代码进行解耦:
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handlerException2")
public CommonResult customerBlockHandler() {
return new CommonResult(200,"按照客户自定义限流测试",new Payment(2020L,"serial003"));
}
在Sentinel中使用资源名称方式,进行限流(使用URL无法使用自定义兜底方法):
测试,完成:
8、服务熔断(Ribbon)
①Ribbon(无配置)
一.Provider
1.新建模块cloudalibaba-provider-payment9003
2.pom依赖:
<dependencies>
<!-- SpringCloud ailibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud ailibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>cn.zko0.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.yml:
server:
port: 9003
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos
management:
endpoints:
web:
exposure:
include: '*'
启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9003 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9003.class,args);
}
}
Controller:
@RestController
public class PaymentController {
@Value("${server.port}") //spring的注解
private String serverPort;
public static HashMap<Long, Payment> map = new HashMap<>();
static {
map.put(1L,new Payment(1L,"1111"));
map.put(2L,new Payment(2L,"2222"));
map.put(3L,new Payment(3L,"3333"));
}
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
Payment payment = map.get(id);
CommonResult<Payment> result = new CommonResult<>(200,"from mysql,serverPort: " + serverPort,payment);
return result;
}
}
按照创建9003的方式创建9004
二.Consuemr
1.创建项目cloudalibaba-consumer-nacos-order84
2.pom:
<dependencies>
<!-- SpringCloud ailibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud ailibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>cn.zko0.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.yml:
server:
port: 84
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos
sentinel:
transport:
dashboard: localhost:8858 #sentinel
client-ip: 192.168.31.30
port: 8719
#消费者将去访问的微服务名称
server-url:
nacos-user-service: http://nacos-payment-provider
#激活Sentinel对Feign的支持
#feign:
# sentinel:
# enabled: true
启动类:
@EnableDiscoveryClient
@SpringBootApplication
public class OrderMain84 {
public static void main(String[] args) {
SpringApplication.run(OrderMain84.class,args);
}
}
RestTemplate的Config:
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
Controller:
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
@SentinelResource(value = "fallback") //没有配置
public CommonResult<Payment> fallback(@PathVariable Long id) {
CommonResult<Payment> result = restTemplate.getForObject(
SERVICE_URL + "/paymentSQL/" + id,CommonResult.class,id);
if(id == 4){
throw new IllegalArgumentException("IllegalArgument,非法参数异常...");
}else if(result.getData() == null) {
throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}
}
三.启动测试
启动
Provider:9003,9004 Consumer:84
当id在1-4范围内,服务正常调用
当服务id>=5,调用出错:
②Ribbon只配置fallback
在前面的Ribbon搭建的结果上,对id>=5的问题配置fallback,进行服务降级处理:
//fallback兜底
public CommonResult handlerFallback(@PathVariable Long id,Throwable e) {
Payment payment = new Payment(id,"null");
return new CommonResult(444,"异常handlerFallback,exception内容: " + e.getMessage(), payment);
}
测试,服务降级成功:
③Ribbon只配置blockHandler
去掉上面fallback的配置
//blockHandler兜底
public CommonResult blockHandler(@PathVariable Long id, BlockException e) {
Payment payment = new Payment(id,"null");
return new CommonResult(444,"blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment);
}
在Sentinel中配置服务降级:
当异常数达到阈值,就会进行服务熔断
服务熔断效果:
④Ribbon配置fallback和blockHandler
先说结论:当fallback和blockHandler同时满足,会优先调用blockHandler
同②,③,将两者配置都打开
进行Sentinel对接口进行流量控制设置:
测试:
当id=1,QPS未达到阈值,正常调用:
当id=1,QPS达到阈值,调用blockHandler方法:
当id=5,QPS未达到阈值,调用fallback方法:
当id=5,QPS达到阈值,调用blockHandler方法:
总结:
当@SentinelResource注解fallback和blockHandler都指定后,然后同时符合,优先执行blockHandler兜底方法。
⑤忽略属性
当在@SentinelResource中配置了exceptionsToIgnore的时候,对于该异常不会调用fallback方法,进行服务降级。
9服务熔断(Feign)
在前面Ribbon搭建的工程上进行修改
1.需要依赖:
<!--前面已添加了-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.yml添加:
#激活Sentinel对Feign的支持
feign:
sentinel:
enabled: true
3.启动类注解添加:
主启动类上添加@EnableFeignClients
4.PaymentService接口
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService {
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
5.PaymentFallbackService实现类,实现PaymentService接口
其实现方法为接口中对应方法的fallback方法
@Component
public class PaymentFallbackService implements PaymentService{
@Override
public CommonResult<Payment> paymentSQL(Long id) {
return new CommonResult<>(444,"服务降级返回,---PaymentFallbackService",new Payment(id,"ErrorSerial"));
}
}
修改Controller:
启动:
如果你在这里出现了下图的错误
在 Hoxton.SR1 中,
fegin.context
接口的定义为parseAndValidatateMetadata
,而在 Hoxton.SR3 中,fegin.context
接口的定义为parseAndValidateMetadata
,就是之前版本中定义的方法名拼写错误,所以在 Hoxton.SR1 后面的版本更正过来,因此出现Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List;
错误。解决方式:将 Spring Cloud 版本升至
Hoxton.SR3
10、规则持久化
在前面的学习中,在每次停止项目的时候,Snetinel规则将会消失。所以我们需要将限流规则持久化。
我们将Sentinel规则持久化保存至Nacos中。
针对8401项目,进行修改和测试:
1.添加依赖:(之前添加过)
<!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2.yml修改:
3.在Nacos添加Sentinel配置:
[
{
"resource": "/rateLimit/byUrl",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
上面的配置对应着Sentinel的限流配置词条:
启动8401,去Sentinel中查看:
可以看到Nacos中配置的限流规则在启动后就能显示,完成了持久化
标签:spring,id,熔断,限流,Sentinel,public,cloud From: https://www.cnblogs.com/zko0/p/17090700.html