前言
Sentinel
是面向分布式架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、服务降级、系统负载保护等多个维度来保障微服务的稳定性,Sentinel
提供了非常灵活且强大的限流能力,支持各种限流的姿势
Sentinel 的组成
- 核心库(Java客户端):不依赖任何框架/库,能够运行于所有的Java运行时环境
- 控制台(Dashboard):基于SpringBoot开发,打包后可直接运行
环境
Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE + Sentinel 1.8.1
整合 Sentinel
pom.xml
<!-- sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.yml
# Actuator
management:
endpoint.health.show-details: always # health
endpoints:
web:
exposure:
include: "*"
- 通过
actuator/sentinel
端点查看sentinel
信息,http://localhost:8010/actuator/sentinel
搭建 Sentinel 控制台
- 下载地址:https://github.com/alibaba/Sentinel/releases
- 这里的
Spring Cloud Alibaba
版本是2.2.6.RELEASE
,对应的Sentinel
版本是1.8.1
- 对应版本可查看:spring-cloud-alibaba版本说明
- 控制台启动
jar
包(指定8083
端口),sentinel
的默认端口是8080
java -jar sentinel-dashboard-1.8.1.jar --server.port=8083
- 访问
Sentinel
控制台http://localhost:8083
- 默认账号密码:
sentinel/sentinel
整合 Sentinel 控制台
application.yml
spring:
application:
# 服务名称
name: content-center
cloud:
sentinel:
transport:
# 指定 sentinel 控制台的地址
dashboard: localhost:8083
-
Sentinel
是懒加载的,访问下微服务的接口才可以看到实时监控详情
- 实时监控展示的是最近几分钟内的
QPS
(每秒查询率)波动
Sentinel与控制台
Sentinel与控制台通信原理
sentinel
实现了一套服务发现机制,微服务需要集成sentinel-transport-simple-http
模块,集成该模块后会把自己注册到Sentinel Dashboard
(控制台),定时给控制台发送心跳,注册到控制台后,控制台就知道每个微服务的地址,就可以调用微服务上的API
来监控健康状况及推送规则
- 通过
actuator/sentinel
端点可查看sentinel
的信息,http://localhost:8010/actuator/sentinel
- 通过
clientIp:clientPort/api
可查看sentinel
控制台与微服务通信的API
应用端连接控制台配置项
spring.cloud.sentinel.transport:
# 指定控制台地址
dashboard: localhost:8083
# 指定通信IP,不配置则自动选择IP注册
client-ip: 127.0.0.1
# 指定通信端口,默认值8719,不配置则从8719开始+1找到未被占用的端口
port: 8719
# 心跳发送周期,默认null
heartbeat-interval-ms: 10000
控制台配置项
- 控制台配置项
配置项 | 默认值 | 描述 |
---|---|---|
server.port | 8080 | 指定端口 |
csp.sentinel.dashboard.server | localhost:8080 | 指定地址 |
project.name | - | 指定程序的名称 |
sentinel.dashboard.auth.username[1.6] | sentinel | Dashboard登录账号 |
sentinel.dashboard.auth.password[1.6] | sentinel | Dashboard登录密码 |
server.servlet.session.timeout[1.6] | 30分钟 | 登录Session过期时间 配置为7200表示7200秒 配置为60m表示为60分钟 |
- 如修改用户名密码
java -jar -Dsentinel.dashboard.auth.username=xxx -Dsentinel.dashboard.auth.password=xxx sentinel-dashboard-1.8.1.jar
流控规则
- 点击簇点链路就可以看到曾经被访问过的路径
- 流控按钮可以为该路径设置流控规则
直接流控模式
- 添加一条直接流控规则,阈值类型为
QPS
,阈值为1
- 该模式顾名思义,当前
API
的QPS
超过阈值时限流
关联流控模式
当关联的资源达到阈值,就限流自己
- 当
/test
端点的QPS
达到阈值时就限流/test4
- 通过循环调用使
/test
端点的访问高于阈值
public static void main(String[] args) throws InterruptedException {
RestTemplate restTemplate = new RestTemplate();
for (int i = 0; i < 1000; i ++) {
String url = "http://localhost:8010/test";
restTemplate.getForObject(url, String.class);
Thread.sleep(500);
}
}
- 当关联的资源
/test
的QPS
高于阈值时,/test4
一直处于限流状态
链路流控模式
只记录指定链路上的流量,指定资源从入口资源进来的流量如果达到阈值时开启限流
Sentinel 1.8.1 链路流控模式失效处理
-
Sentinel
链路流控模式失效:https://github.com/alibaba/sentinel/issues/1213 -
pom.xml
中添加新依赖
<!-- sentinel 1.8.1 链路流控模式失效 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
</dependency>
- 关闭
sentinel
的CommonFilter
实例化
spring.cloud.sentinel.filter.enabled=false
链路流控模式测试
TestController.java
@RestController
public class TestController {
@Autowired
private TestService testService;
@GetMapping("test_a")
public String test_a() {
testService.common();
return "test_a";
}
@GetMapping("test_b")
public String test_b() {
testService.common();
return "test_b";
}
}
TestService.java
@Service
public class TestService {
// @SentinelResource注解用于定义资源
@SentinelResource("common")
public void common() {
System.out.println("common");
}
}
- 访问两个接口后就有了簇点链路
- 配置
/test-a
->common
的流控规则为链路
- 频繁访问,当入口
/test_a
的QPS
超过阈值时被限流
- 而
/test_b
正常访问
链路流控模式与关联流控模式的区别
链路流控模式是一种细粒度的针对来源,是API级别的,而关联流控模式微服务级别的
流控效果
快速失败
- 直接失败抛异常
Warm Up
-
Warm Up
可以让允许通过的流量缓慢的增加,再经过预热时长后才达到设置的QPS
阈值
排队等待
- 匀速排队,让请求以均匀的速度通过,阈值类型必须设置为
QPS
,否则无效
- 如上,
1s
只允许1
次请求,其余请求在后排队,直到超过超时时间而丢弃请求