背景
Sentinel 是流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
【场景】业务服务稳定性保障,流量治理(流量控制、限流、熔断降级、系统负载保护)。
业务研发希望,通过Sentinel提供的流控防护能力,保障业务核心服务的稳定性。
历史原因,公司使用Apollo作为配置中心,但Sentinel开源框架和社区并未提供Apollo的持久化配置方案。
Sentinel
可选内容,可跳过
https://sentinelguard.io/zh-cn/
Sentinel,面向分布式、多语言异构化服务架构的流量治理****组件
Sentinel,A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
简介
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。
特性一览
丰富的应用场景
阿里巴巴 10 年双十一积累的丰富流量场景,包括秒杀、双十一零点持续洪峰、热点商品探测、预热、消息队列削峰填谷等多样化的场景
多样化的流量控制
资源粒度、调用关系、指标类型、控制效果等多维度的流量控制
易于使用,快速接入
简单易用,开源生态广泛,针对 Dubbo、Spring Cloud、gRPC、Zuul、Reactor、Quarkus 等框架只需要引入适配模块即可快速接入
可视化的监控和规则管理
简单易用的 Sentinel 控制台
微服务生态全景图
快速开始
只需 5 分钟即可快速熟悉 Sentinel
使用文档
基本使用 - 资源与规则
https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html
使用 Sentinel 来进行资源保护,主要分为几个步骤:
- 定义资源
- 定义规则
- 检验规则是否生效
Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
注解埋点支持
Sentinel 提供了 @SentinelResource
注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException
等。
Sentinel 控制台
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群) ,规则管理和推送的功能。
Sentinel 控制台包含如下功能:
-
查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
-
监控 (单机和集群聚合) :通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
-
规则管理和推送:统一管理推送规则。
-
鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
开源的实现方案调研
sentinel-dashboard-push
rowstop
基于Sentinel 1.8.7
,支持双向持久化到配置中心。支持 Gateway 模式与常规模式,支持原始模式、Nacos、Apollo
sentinel-dashboard-apollo
fengjx
sentinel-dashboard 定制版,支持 apollo 持久化配置
sentinel-dashboard-X
finefuture
Sentinel Dashboard 集成多数据源版本
apollo-sentinel-dashboard
hosaos
sentinel-dashboard整合apollo配置中心
Anilople/Sentinel
A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
Apollo持久化规则配置
集成Apollo配置中心的方案
- 应用隔离(ApplicationId) ,Sentinel管控台统一操作,授权简单 ✅
- 应用命名空间隔离(namespaceName),平台视角的操作闭环,统一在Sentinel管控台
- 配置项隔离(itemKey,
application
命名空间)
应用接入使用指南
应用接入示例
五步走,10分钟搞定
- 一、增加boot-starter依赖
- 二、流量治理接入示例代码
- 三、增加属性配置项
- 四、输出Sentinel日志到应用日志
- 五、配置接口方法的资源规则
应用首次接入发布,每个环境都需要找运维开放 8719 端口!
一、增加Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- 可选版本 -->
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<properties>
<xxx-boot.version>2.1.0</xxx-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- sentinel -->
<dependency>
<groupId>org.spring.boot</groupId>
<artifactId>xxx-spring-boot-starter-sentinel</artifactId>
<version>${xxx-boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- sentinel -->
<dependency>
<groupId>org.spring.boot</groupId>
<artifactId>xxx-spring-boot-starter-sentinel</artifactId>
</dependency>
</dependencies>
二、流量治理接入示例代码
接口方法
资源名称: {服务名称}.{方法名称}
import org.springframework.stereotype.Service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
@Service
public class SentinelService {
@SentinelResource(value = "SentinelService.sayHello", blockHandler = "sayHelloBlockHandler")
public String sayHello(String name) {
return "Hello, " + name;
}
// 参数签名与限流方法一样
public String sayHelloBlockHandler (String name, BlockException e) {
return name + ": 请稍后重试" ;
}
}
api 端点
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.demo.datasource.service.SentinelService;
import com.alibaba.csp.sentinel.slots.block.BlockException;
@RestController
public class SentinelController {
private final SentinelService sentinelService;
public SentinelController(
SentinelService sentinelService
) {
this.sentinelService = sentinelService;
}
@SentinelResource(value = "/hello", blockHandler = "helloBlockHandler")
@GetMapping(value = "/hello/{name}")
public String sayHello(@PathVariable String name) {
return sentinelService.sayHello(name);
}
// 参数签名与限流方法一样
public String helloBlockHandler (String name, BlockException e) {
return name + ": 请稍后重试";
}
}
三、增加属性配置项
增加sentinel
端点
management:
endpoints:
web:
exposure:
# sentinel端点
include: xxx,sentinel
prod 生产环境配置项
application-production.yml
spring:
cloud:
sentinel:
eager: true
filter:
enabled: false
transport:
dashboard: https://prod-sentinel-dashboard.xxx-inc.com
# dashboard: http://sentinel-dashboard:8080
datasource:
dataSourceName:
http:
dashboard-url: ${spring.cloud.sentinel.transport.dashboard}
app-name: ${spring.application.name}
rule-type: flow
INFO: Sentinel log output type is: file
INFO: Sentinel log charset is: utf-8
INFO: Sentinel log base directory is: /Users/lihuagang/logs/csp/
INFO: Sentinel log name use pid is: false
INFO: Sentinel log level is: INFO
四、输出Sentinel日志到应用日志
问题便于排查分析。
logback-spring.xml
<logger name="sentinelRecordLogger" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</logger>
<logger name="sentinelCommandCenterLogger" level="WARN" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</logger>
五、配置资源规则
Sentinel 控制台
https://sentinelguard.io/zh-cn/docs/dashboard.html
资源规则配置由Sentinel 控制台统一管控,默认用户名和密码都是 sentinel
。
4.查看机器列表
以及健康情况
应用实例上报后,才可见。
5.监控
5.1 "簇点链路
"中显示刚刚调用的资源(单机实时)
资源方法调用后,才可见。
5.2 "实时监控
"汇总资源信息(集群聚合)
6.规则管理及推送
6.1 规则管理
6.2 规则推送
踩过的坑
应用编译报错"Unsupported major.minor version"
sentinel-datasource-http-1.8.8.jar
发布后,发现使用的JDK版本是17,不是1.8。
解决方法,调整maven-compiler-plugin
插件的编译目标JDK版本为1.8
。
sentinel-dashboard
应用域名在K8s扩容实例不生效,引起应用实例注册失败
http://sentinel-dashboard:8080
中的sentinel-dashboard
应用域名,在Kubernetes扩容实例时不生效,引起应用实例注册失败。在Sentinel控制台的这个应用的机器列表中,看不到扩容的实例节点。
具体原因,阿里云还在排查中,怀疑可能是SCI网络策略问题。
临时解决方法,使用https://prod-sentinel-dashboard.xxx-inc.com作为控制台地址。
sentinel-dashboard
缺少JVM监控
应用监控中看不到JVM监控,JVM实例资源使用状况是黑盒,不确定因素。
- 增加
prometheus
端点
Sentinel日志被输出到sentinel-record.log
sentinel-record.log
在~/logs/csp/
目录下,不能收集到日志服务平台供开发快速查询。
最好输出到应用日志文件,这样就能收集到日志服务平台。
- Sentinel日志输出到应用日志文件,使用
sentinel-logging-slf4j
组件适配日志到slf4j
sentinel-dashboard
应用实例有多个,登录态经常退出
登录态令牌存储在内存中,需要迁移到Redis分布式缓存,解决资源共享的问题。
临时解决方法,生产环境只有1个实例节点。
- 登录态令牌从内存迁移到Redis分布式缓存
从 Sentinel 1.5.0 开始,控制台提供通用的鉴权接口 AuthService,用户可根据需求自行实现。
机器列表的实例的健康状态是失联,未自动移除
【解法】通过autoRemoveMachineMillis
配置有效值,-Dsentinel.dashboard.autoRemoveMachineMillis=600000
。
距离最近心跳时间超过指定时间是否自动删除失联节点,默认关闭。