随着微服务的流行,服务和服务之间的稳定性变得越来越重要。以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
1. Sentinel 介绍1.1 知识Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。
Sentinel 的组成:
- (1) Sentinel 核心库, 即基本的类库的使用。
- (2) Dashboard 控制台,即web页面的使用。
本章节主要说 核心库 的使用。
使用 Sentinel 来进行资源保护,主要分为几个步骤:
- 定义资源
- 定义规则
- 检验规则是否生效
也就是说:
- 先把可能需要保护的资源定义好(即埋点)
- 之后再配置规则,规则描述了什么方式来保护资源。
- 声明了资源,后续在任何时候灵活地定义各种流量控制规则。
定义资源的方式资源:可以是指一个服务,一个服务里的方法,或者是一段代码。写代码时,考虑某段代码是否需要保护,如果需要就将之定义为一个资源。
sentinel 支持都多种方式来定义资源,常见的有:
- 方式一:整合到常见的主流框架,比如 Web Servlet、Dubbo、Spring Cloud
- 方式二:抛出异常的方式,使用 SphU 这个类的 try-catch 方式
- 方式三:返回布尔值方式定义资源,使用 SphO 提供 if-else 风格的 API
- 方式四:注解方式定义资源,使用 @SentinelResource 注解 。
- 方式五:异步调用支持,使用 SphU.asyncEntry 异步方法。
示例有:抛出异常的方式 来定义资源
使用 SphU 这个类的 try-catch 风格的 API。当“资源”发生了限流之后会抛出 BlockException,然后捕捉异常进行限流之后的逻辑处理。
示例代码如下:
try (Entry entry = SphU.entry("resourceName")) {
// 被保护的业务逻辑
// do something here...
} catch (BlockException ex) {
// 资源访问阻止,被限流或被降级
// 在此处进行相应的处理操作
}
规则
Sentinel 支持以下几种规则:
- 流量控制规则
- 熔断降级规则
- 系统保护规则
- 来源访问控制规则
- 热点参数规则
流量控制规则(FlowRule)
支持 QPS 模式(1)或并发线程数模式(0)。
熔断降级规则(DegradeRule)
熔断策略,支持慢调用比例/异常比例/异常数策略
系统保护规则 (SystemRule)
结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡
来源访问控制规则 (AuthorityRule)
即黑名单,白名单规则。
规则的持久化方式:和 nacos 一起使用
可以和 nacos 一起使用,将规则持久化存储到 nacos 中。
示例:
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel spring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUP spring.cloud.sentinel.datasource.ds2.nacos.data-type=json spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
数据源都的配置项说明:
- data-type 配置项说明格式,分别是 json 和 xml (不填默认是json)
- rule-type 配置表示该数据源中的规则属于哪种类型的规则(flow,degrade,authority,system, param-flow, gw-flow, gw-api-group)。
注意
数据源的依赖要单独引入(比如 sentinel-datasource-nacos)。
一般java web 项目都会有 controller 层, service 层,dao层,我们要在 service 层使用的是可以这么做。
(1)添加依赖
com.alibaba.cloud spring-cloud-starter-alibaba-sentinel
(2) 在服务层加注解:
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
@SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 value 指示了一个资源名称。
@SentinelResource 还提供了其它额外的属性如 blockHandler,blockHandlerClass,fallback 用于表示限流或降级的操作
一般我们需要实现一个降级后的处理,比如上面的 fallback 指示一个降级后字符串返回值告知触发了熔断降级。
另外,Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。我们在后面用一个章节来介绍它。
1.3 和 Feign 一起使用Sentinel 适配了组件。
(1) 先引入 spring-cloud-starter-alibaba-sentinel 的依赖(2) 再引入feign依赖
引入 spring-cloud-starter-openfeign 依赖**,使 Sentinel starter 中的自动化配置类生效:
org.springframework.cloud spring-cloud-starter-openfeign
(3) 配置文件打开
配置文件打开 Sentinel 对 Feign 的支持:
feign.sentinel.enabled=true
示例说明
比如下面的示例中你要了解的:
- 1.正常的业务调用: /echo/{str}。
-
- 熔断后的异常处理,指定了 fallback 处理,并返回 "echo fallback" 字符串。
详细示例:
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
1.4 和 RestTemplate 一起使用
支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,加上 @SentinelRestTemplate 注解。
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
说明:@SentinelRestTemplate 注解的属性
@SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。
比如上面的示例指示了 ExceptionUtil.handleException 是熔断降级后的异常处理方法,该方面用明确的方法签名格式,如下:
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
方法返回值提供了 SentinelClientHttpResponse 用于构造返回信息。
注意
应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常
实际项目中也会在网关层使用,见下一章节。
2. 在 Spring Cloud Gateway 网关中使用可以结合 Spring Cloud Gateway 一起使用。
- (1) 添加 spring-cloud-alibaba-sentinel-gateway 依赖。
- (2) 添加 spring-cloud-starter-gateway 依赖
来让 spring-cloud-alibaba-sentinel-gateway 模块里的 Spring Cloud Gateway 自动化配置类生效:
com.alibaba.cloud spring-cloud-starter-alibaba-sentinelcom.alibaba.cloud spring-cloud-alibaba-sentinel-gatewayorg.springframework.cloud spring-cloud-starter-gateway
- (3) 配置文件
指定 spring.cloud.sentinel.filter.enabled 为 false
注意:
网关流控规则数据源类型是 gw-flow,若将网关流控规则数据源指定为 flow 则不生效。
支持两种资源标识维度的限流
Sentinel 提供的 Spring Cloud Gateway 的适配模块可以提供两种资源维度的限流:
- routeId:即在 gateway 中的路由 routeId。
- 自定义分组的名称:可以利用 API 来自定义一些分组名,将URL归类在一个组下。
- 默认不支持 URL 粒度
- 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
- 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
- 规则管理和推送:统一管理推送规则。
- 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
下载最新版本的控制台 jar 包
可以从这个 release 页面 下载。
命令行启动
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456
说明:
- -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080,浏览器从这个端访问。打开页面,默认用户名和密码都是 sentinel。
管理和新增规则
打开 http://localhost:8080
您可以在 控制台web页 配置修改规则,进行规则管理。
点击新增规则按钮,如下:
image.png规则的存储
默认是存储在内存的,应用重启之后该规则会丢失。建议通过一些配置来使用外部存储方式来保存。建议结合 nacos 动态实时的刷新规则。
规则推送分为 3 种模式,包括:
- 原始模式
- Pull 模式
- Push 模式"。
通过 API 将规则推送至客户端并直接更新到内存中, 图例:
------> sentinel 客户端1
Sentinel ------> sentinel 客户端2
Dashboard
------> sentinel 客户端3
好处: 简单,无依赖;
坏处: 应用重启规则就会消失,不能用于生产环境
在客户端注册一个本地文件数据源:收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中。
本地文件数据源会定时轮询文件的变更,读取规则。
这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。
以本地文件数据源为例,过程如下图所示:
/---------- 在内存中更新规则(规则缓存)
/
Sentinel -----> Sentinel客户端 ----> 将规则写入本地文件 ----> 本地文件
Dashboard
好处:简单,不引入新的依赖
坏处:无法保证监控数据的一致性
Sentinel 控制台 的规则到 统一配置中心(比如nacos),再到各个 客户端。
即: Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel
图例:
nacos
(1) /
/ (2)
/
Sentinel |---- sentinel 客户端1
Dashboard |---- sentinel 客户端2
生产环境建议使用 PUSH 模式。
4. 参考Sentinel 控制台https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinelhttps://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinelhttps://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel



