
(1)理论基础
http://sentinelguard.io/zh-cn/docs/introduction.html
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状
熔断降级
什么是熔断降级
除了流量控制以外,降低调用链路中的不稳定资源也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。这个问题和 Hystrix 里面描述的问题是一样的。
Sentinel 和 Hystrix 的原则是一致的: 当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。
(2)配置
(1)启动服务
java -jar -Dserver.port=9100 sentinel-dashboard-1.8.5.jar
(2)pom依赖
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.1</version>
</dependency>
(3)yml配置
spring:
cloud:
sentinel:
eager: true #服务启动直接建立心跳连接
transport:
port: 8719 # 假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口,默认8719
dashboard: 127.0.0.1:9100 # 指定控制台服务的地址
feign:
client:
config:
# 默认的超时时间设置
default:
connectTimeout: 5000
readTimeout: 5000
# 在指定的 FeignClient 设置超时时间,覆盖默认的设置
nacos-provider:
connectTimeout: 1000
readTimeout: 1000
loggerLevel: full
# 激活 Sentinel
sentinel:
enabled: true
(4)解决循环依赖问题:
spring:
main:
allow-circular-references: true
(3)项目应用
@RestController
public class A {
// 流控测试:QPS
// 流控模式:直接、关联、链路
// 流控效果:快速失败、Warm up、排队等待
@RequestMapping("m1")
public String m1(){
System.out.println("m1...................................");
return "m1";
}
// 流控测试:并发线程数
@RequestMapping("m2")
public String m2(){
System.out.println("m2...................................");
return "m2";
}
}
/*
特别注意:
feign:
sentinel:
enabled: true
*/
@RestController
public class B {
// 熔断规则慢调用比例测试
// RT500、比例阈值1、熔断时长5、最小请求数1、统计时长1000
@RequestMapping("m3")
@SentinelResource(value = "m3", blockHandler = "test3")
public String m3() throws InterruptedException {
Thread.sleep(1000);
System.out.println("m3...................................");
return "m3";
}
String test3(BlockException e){
System.out.println(e);
return "慢调用熔断降级";
}
// 熔断规则异常数测试
// 比例阈值1、熔断时长5、最小请求数2、统计时长1000
@RequestMapping("m4")
@SentinelResource(value = "m4", blockHandler = "test4")
public String m4(){
int i = 4 / 0;
System.out.println("m4...................................");
return "m4";
}
String test4(BlockException e){
System.out.println(e);
return "异常数熔断降级";
}
}