一、简介
Sentinel 是一个高可用、高扩展、高稳定性的开源流量控制和熔断降级框架,可以在分布式系统中实现实时的流量控制,防止系统因流量过大导致系统崩溃和服务降级。
Sentinel 提供了以下功能:
- 流量控制:通过配置不同的规则,对请求流量进行限制。
- 熔断降级:当系统异常情况发生时,可以自动熔断系统,保证系统的可用性。
- 系统负载保护:在系统负载高峰期间,可以限制请求流量,避免系统资源耗尽。
- 实时监控:可以实时监控系统的请求流量、响应时间、错误率等指标。
Sentinel 面向所有的 Java 应用,可以支持基于 Spring Cloud、Dubbo、gRPC 等服务框架的应用,也可以集成到基于 Tomcat、Jetty 等 Web 容器的应用中。
二、Sentinel 的原理
Sentinel 实现流量控制和熔断降级的原理是通过对应用程序进行拦截,然后根据预定义的规则,来判断该请求是否被允许或者需要进行降级处理。
Sentinel 的拦截器会在应用程序中建立一个责任链,对请求进行逐一拦截。在拦截过程中,Sentinel 会对 Request、Response、Exception 等参数进行统计,根据统计信息来对请求进行熔断或者限流等操作。
衡量系统稳定性主要有以下三个指标:
- TPS(Transactions Per Second):每秒钟处理的事务数。
- RT(Response Time):响应时间,即从发送请求到接收到响应的时间。
- Error Rate:错误率,即发生错误的请求次数占总请求数的比例。
Sentinel 根据这三个指标来评估应用程序的健康状况,当这些指标达到某个阈值时,Sentinel 会自动触发相应的流量控制和熔断降级操作。
三、Sentinel 快速入门
以下是 Sentinel 快速入门的几个步骤:
-
首先,在 Maven 中引入 Sentinel 的依赖:
xml复制代码
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.1.RELEASE</version> </dependency>
-
在 Spring Boot 中配置 Sentinel 的启动参数:
properties复制代码
spring.cloud.sentinel.transport.dashboard=http://localhost:8080 spring.cloud.sentinel.transport.port=8719 # Sentinel 控制台连接超时时间(ms) spring.cloud.sentinel.transport.dashboard.request-timeout=5000 # 配置资源的默认规则 spring.cloud.sentinel.rules.defaults[0].grade=QPS spring.cloud.sentinel.rules.defaults[0].count=10
其中,
spring.cloud.sentinel.transport.dashboard
配置了 Sentinel 控制台的地址,spring.cloud.sentinel.transport.port
配置了 Sentinel 的启动端口。 -
在需要进行流量控制的方法上添加注解:
java复制代码
@SentinelResource(value = "demoMethod", blockHandler = "handleBlock") public String demoMethod() { return "Hello World"; } public String handleBlock(BlockException ex) { return "请求被拦截: " + ex.getClass().getSimpleName(); }
在上述代码中,我们使用
@SentinelResource
注解对demoMethod
方法进行了流量控制,并设置了 fallback 方法为handleBlock
。当触发限流时,就会执行handleBlock
方法来返回自定义的响应结果。
四、使用 Sentinel 进行熔断降级
Sentinel 不仅能够进行流量控制,还能够进行熔断降级。当系统出现一定程度的异常时,就会触发熔断降级策略来保证系统的可用性。以下是使用 Sentinel 进行熔断降级的几个步骤:
-
在业务方法上添加
java@SentinelResource
注解,并指定fallbackClass
和fallback
属性值:复制代码
@SentinelResource(value = "demoMethod", blockHandler = "handleBlock", fallbackClass = DemoServiceFallback.class, fallback = "fallback") public String demoMethod() { return "Hello World";