SpringCloud——熔断与限流 Sentinel
1. Sentinel 概述
官网:https://github.com/alibaba/Sentinel
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
1.1 功能
1.2 控制台安装
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
下载:
https://github.com/alibaba/Sentinel/releases
下载到本地 sentinel-dashboard-1.7.0.jar
运行:java -jar sentinel-dashboard-1.7.0.jar
访问:http://localhost:8080 登录账号密码均为 sentinel
1.3 流控规则
资源名:唯一名称,默认请求路径。
针对来源:Sentinel 可以针对调用者进行限流,填写微服务名,默认default (不区分来源)。
阈值类型/单机阈值:
- QPS (每秒钟的请求数量) :当调用该 api 的 QPS 达到阈值时,进行限流
- 线程数:当调用该 api 的线程数达到阈值时,进行限流
流控模式:
- 直接: api 达到限流条件时, 直接限流
- 关联:当关联的资源达到阈值时, 就限流自己
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)
流控效果:
- 快速失败:直接失败,抛出 Blocked by Sentinel (flow limiting)
- Warm Up:根据 codeFactor (冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
- 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
1.4 降级规则
RT (平均响应时间)
平均响应时间超出阈值且在时间窗口内通过的请求>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器。RT最大4900 (更大的需要通过Dcsp.sentinel.statisti .max.t=XXXX才能生效)
异常比列(秒级)
QPS>= 5且异常比例(秒级统计)超过阈值时触发降级,时间窗门结束后关闭降级。
异常数(分钟级)
异常数(分钟统计)超过阈值时触发降级,时间窗口结束后关闭降级。
1.5 热点限流
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。
1.6 系统规则
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
2. 熔断框架比较
3. 服务熔断
3.1 @SentinelResource
@SentinelResource 用于定义资源,并提供可选的异常处理和fallback配置项。
属性说明
value:
资源名称,必需项。因为需要通过resource name找到对应的规则。
entryType:
entry 类型,可选项,
有IN和OUT两个选项,默认为 EntryType.OUT。
public enum EntryType {
IN("IN"),
OUT("OUT");
}
blockHandler:
blockHandler 对应处理 BlockException 的函数名称,可选项。
blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,
参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。
blockHandlerClass:
blockHandler 函数默认需要和原方法在同一个类中,如果希望使用其他类的函数,
则需要指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallback:
fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
fallbackClass:
fallbackClass的应用和blockHandlerClass类似,fallback 函数默认需要和原方法在同一个类中。
若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
defaultFallback(since 1.6.0):
如果没有配置defaultFallback方法,默认都会走到这里来。
默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑。
默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。
exceptionsToIgnore(since 1.6.0):
用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
3.2 实现服务熔断
pom:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</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>
YML:
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos 服务注册中心
sentinel:
transport:
dashboard: localhost:8080 # Sentinel dashboard 地址
port: 8719 # 默认8719,如果被占用从 8719 开始依次 +1 扫描,直至找到未被占用的端口
management:
endpoints:
web:
exposure:
include: '*'
主启动:
@SpringBootApplication
@EnableDiscoveryClient
public class MainApp8401 {
public static void main(String[] args){
SpringApplication.run(MainApp8401.class,args);
}
}
业务类:
@RestController
public class RateLimitController {
@GetMapping("/byResource")
@SentinelResource(value = "byResource",
blockHandlerClass = CustomerBlockHandler.class,
blockHandler = "handleException",
fallback = "byResourceFallback")
public String byResource()
{
return "按资源名称限流测试OK";
}
public String byResourceFallback()
{
return "服务降级返回";
}
}
流控规则:
测试:
业务类添加异常:
4. 规则持久化
重启服务后,Sentinel 中对应的规则将消失,生产环境需要将配置规则进行持久化。
实现:将限流配置规则持久化进 Nacos 保存,只要 Nacos 里面的配置不删除,对应服务在 Sentinel 上的流控规则持续有效。
pom:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
yml:
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos 服务注册中心
sentinel:
transport:
dashboard: localhost:8080 # Sentinel dashboard 地址
port: 8719 # 默认8719,如果被占用从 8719 开始依次 +1 扫描,直至找到未被占用的端口
datasource:
ds1: # 数据源1
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service # 微服务名称
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
management:
endpoints:
web:
exposure:
include: '*'
Nacos 中添加规则配置:
[
{
"resource": "/byResource",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
- resource:资源名称;
- limitApp:来源应用;
- grade:阈值类型,0表示线程数, 1表示QPS;
- count:单机阈值;
- strategy:流控模式,0表示直接, 1表示关联, 2表示链路;
- controlBehavior:流控效果,0表示快速失败,1表示Warm Up, 2表示排队等待;
- clusterMode:是否集群。
启动服务就可以在 sentinel 中看见规则了:
推荐阅读
-
SpringCloud Alibaba Sentinel实现熔断与限流
-
Spring Cloud Alibaba:Sentinel实现熔断与限流
-
SpringCloudAlibaba笔记——Sentinel实现熔断与限流
-
Sentinel实现熔断与限流
-
SpringCloud Alibaba Sentinel实现熔断与限流
-
SpringCloud Alibaba Sentinel实现熔断与限流
-
SpringCloud——熔断与限流 Sentinel
-
Spring Cloud Alibaba之Sentinel实现熔断限流功能
-
这个注解一次搞定限流与熔断降级:@SentinelResource
-
SpringCloud之Hystrix【服务降级、服务熔断、服务限流】