Sentinel 使用记录
Sentinel是什么
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。(来源于官方文档)
个人使用感觉:类似于 Hystrix,使用上感觉比 Hystrix 更容易,功能也更强大。
架构说明
两个生产者服务运行在 9001 和 9002 端口,一个消费者服务运行在 80 端口,均注册到 nacos,消费者调用两个生产者的服务。
将消费者服务注册到 sentinel 中,通过修改一些规则进行测试。
controller 下的方法指定好处理服务限流,降级或熔断等的方法 blockHandler,以及处理未知异常的 fallback 方法,通过指定 class 的方法避免代码膨胀。
service 下的方法指定好关于生产者的服务限流,降级或熔断等的处理方法。
代码编写记录
生产者端
配置
关于 nacos 的配置省略,只记录 sentinel 的配置:
1spring:
2 application:
3 name: nacos-payment-provider
4 cloud:
5 sentinel:
6 transport:
7 dashboard: localhost:8080
8 port: 8179
接口编写
1@RestController
2@Slf4j
3public class PaymentController {
4 @Value("${server.port}")
5 private String port;
6
7 @GetMapping("/payment/nacos/info")
8 public String paymentInfo() {
9 return "port: " + port;
10 }
11}
返回对应端口,方便测试负载均衡。
消费者端
配置
1spring:
2 application:
3 name: nacos-order-consumer
4 sentinel:
5 transport:
6 dashboard: localhost:8080
7 port: 8179
8feign:
9 sentinel:
10 enabled: true
注意要开启 feign 的 sentinel 支持。
依赖
1<dependency>
2 <groupId>com.alibaba.cloud</groupId>
3 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
4</dependency>
服务编写
1@FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
2@Service
3public interface PaymentService {
4 @GetMapping("/payment/nacos/info")
5 String paymentInfo();
6}
对应实现类:
1@Service
2public class PaymentFallbackService implements PaymentService{
3 @Override
4 public String paymentInfo() {
5 return "feign::fallback";
6 }
7}
这里处理关于生产者的服务限流,降级或熔断问题。
两个服务问题 Hanlder 的编写
根据官方文档,这里的方法都需指明为 static,否者无法识别。
1@Component
2public class GlobalBlockHandler {
3 public static String block1(BlockException e) {return "block1";}
4 public static String block2(BlockException e) {return "block2";}
5}
这个用于消费者端处理服务限流,降级或熔断等问题。
1@Component
2public class GlobalFallbackHandler {
3 public static String fallback1() {return "fallback1";}
4 public static String fallback2() {return "fallback2";}
5}
这个用于消费者端处理未知异常。
五、controller 编写
1@RestController
2@Slf4j
3public class OrderController {
4 @Resource
5 PaymentService paymentService;
6
7 @GetMapping("/consumer/payment/nacos/info")
8 @SentinelResource(
9 value = "paymentInfo",
10 fallbackClass = GlobalFallbackHandler.class, fallback = "fallback1",
11 blockHandlerClass = GlobalBlockHandler.class, blockHandler = "block1"
12 )
13 public String paymentInfo() {
14 int a = 1 / 0;
15 return paymentService.paymentInfo();
16 }
17}
指定好 class 的同时,需用 fallback 和 blockHandler 分别指定好具体的方法名。
测试
一、测试除 0 错误是否正确进入 fallback1:直接访问接口,返回 “fallback1”,正确;
二、测试消费者端服务限流:sentinel 指定流控规则,QPS 设置阈值为 1,连续访问接口,返回 “block1”,正确;
三、测试生产者端除 0 错误是否正确进入 fallback:给生产者 controller 添加除 0 错误,访问接口,返回 “feign::fallback”,正确;
四、测试其他服务规则:
指定熔断规则,熔断策略选为慢调用比例,最大 RT(Round Trip Time,也叫响应时间)设置为 200ms,比例阈值设置为 0.5,最小请求数设置为 5。
为模拟慢调用,手动增大发出接口请求到收到结果的延迟,在 controller 中添加 Thread.sleep(1000)
,延迟 1 秒。
连续访问接口,首先返回了“9001”,即访问正常时得到的结果,然而发现在 5 次以上的请求以后,返回了 “block1”,成功熔断。