Sentinel 使用记录

5 minute

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”,成功熔断。