什么是Sentinel
Sentinel是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性
安装Sentinel
1、下载Sentinel控制台:
所有Sentinel版本的jar包下载地址:https://github.com/alibaba/Sentinel/releases
阿里sentinel github地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md
2、启动sentinel
到达指定目录后,输入java -jar sentinel-dashboard.jar,启动默认为8080端口
3、访问控制台
在浏览器上输入 http://localhost:8080 如果sentinel是1.6.0版本需要进行登录,默认账号:sentinel,密码:sentinel
输入地址后,显示如下图说明控制台启动成功:
编写sentinel实例
1、添加pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
2、application.properties文件添加相应的配置信息
server.port=9977
#应用名称,在限流的控制台中显示
spring.application.name=sentinel-example
#限流控制台的地址和端口
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
3、添加SentinelResource注解和创建对应的blockHandler类文件
SentinelTestController.java
package com.example.wlztest.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.wlztest.util.SentinelExceptionUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SentinelTestController {
@SentinelResource(value = "sentinelTest", blockHandler = "exceptionHandler"
, blockHandlerClass = { SentinelExceptionUtil.class }
, fallback = "fallbackHandler")
@RequestMapping(value = "/sentinelTest",method = RequestMethod.GET)
@ResponseBody
public String sentinelTest(long s){
System.out.println("执行了sentinelTest方法");
return "执行了sentinelTest方法";
}
// Fallback 函数,函数签名与原函数一致.
public static String fallbackHandler(long s) {
return String.format("调用了helloFallback方法", s);
}
}
SentinelExceptionUtil.java
package com.example.wlztest.util;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class SentinelExceptionUtil {
//异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
public static String exceptionHandler(long s, BlockException ex) {
ex.printStackTrace();
return "调用SentinelExceptionUtil中的exceptionHandler方法" + s;
}
public static String exceptionHandler2(String str, BlockException ex) {
ex.printStackTrace();
return "调用SentinelExceptionUtil中的exceptionHandler2方法 " + str;
}
}
以下为SentinelResource注解的属性说明
属性 |
作用 |
是否必填 |
value |
资源名称 |
是 |
entryType |
entry类型,标记流量的方向,取值IN/OUT,默认是OUT |
否 |
blockHandler |
处理BlockException的函数名称。函数要求: 1. 必须是 public 2.返回类型与原方法一致 3. 参数类型需要和原方法相匹配,并在最后加 BlockException 类型的参数。 4. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法。 |
否 |
blockHandlerClass |
存放blockHandler的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同blockHandler。 |
否 |
fallback |
用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。函数要求: 1. 返回类型与原方法一致 2. 参数类型需要和原方法相匹配,Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。 3.默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定fallbackClass里面的方法。 |
否 |
fallbackClass【1.6】 |
存放fallback的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。 |
否 |
defaultFallback【1.6】 |
用于通用的 fallback 逻辑。默认fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求: 1. 返回类型与原方法一致 2. 方法参数列表为空,或者有一个 Throwable 类型的参数。 3. 默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定 fallbackClass 里面的方法。 |
否 |
exceptionsToIgnore【1.6】 |
指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。 |
否 |
exceptionsToTrace |
需要trace的异常 |
Throwable |
通过sentinel控制台配置限流规则
1、启动测试工程和sentinel控制台,可以看到下图,控制台中显示当前所启动的应用
2、点击簇点链路按钮,来到簇点链路的操作页面
3、选中一个资源点击流控按钮,配置流控条件
4、点击流控规则按钮,查看规则是否正确配置
5、上图我们将资源名为sentinelTest的埋点配置了QPS为3的流控条件,我们在浏览器访问 http://localhost:9977/sentinelTest?s=1 ,并快速刷新多次,页面内容由:
转变为:
说明成功触发流限规则,再看主控制台的实时监控页面,如红色标记,通过QPS最高为3,符合流限规则设置:
以上为使用sentinel进行流限控制的DEMO和演示流程。
Sentinel问题
1、单纯使用sentinel,规则无法进行持久化,在关闭、重启工程后,所配置的规则会丢失。需要自己进行额外的持久化操作,目前网上有一些接合Nacos或是本地文件进行规则初始化的用例。
2、使用Nacos进行规则初始化,如配置了下列依赖,会导致sentinel控制台的规则配置失效,只能读取Nacos中设置的规则,比较不灵活,原因是因为当前版本的sentinel控制台设置规则,不具备修改规则后对Nacos配置的的规则进行同步的能力。导致之后的配置新规则都需要在Nacos控制台中进行配置,然后推送给sentinel,造成sentinel控制台规则配合的作用下降。(此问题是本人暂无解决方法,如果有方法可以解决Sentinel控制台同步修改Nacos规则,麻烦给我留言)
<!--sentinel指定nacos为数据源 -->
<!--<dependency>-->
<!--<groupId>com.alibaba.csp</groupId>-->
<!--<artifactId>sentinel-datasource-nacos</artifactId>-->
<!--<version>1.6.0</version>-->
<!--</dependency>-->
3、结合本地文件进行Pull ,不能保证一致性、拉取过于频繁也可能会有性能问题等。
4、实时监控默认只能监控近6秒的数据,如果想监控长时间的数据需要自己进行改造,并进行数据持久化。
5、如果你的Sentinel控制台原本是1.6.0之前的版本,现在改成了1.6.0,出现控制台显示失败或数据异常的问题。请清除缓存,关闭浏览器再进行访问,个人猜想可能是因为1.6.0增加了登录功能的原因。
6、目前阿里有成熟的Sentinel产品,已经解决了持久化等问题,有需要也可以进行了解和借鉴。