sentinel的官方名称叫分布式系统的流量防卫兵。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。在Spring Cloud项目中最开始咱们使用的是Hystrix,目前已中止更新了。如今Spring Cloud官方推荐的是rensilience4j。固然还有咱们今天学习的sentinel。java
Sentinel 具备如下特征:git
这里咱们直接下载jar包便可,下载后经过命令行启动:github
java -jar sentinel-dashboard-1.7.2.jar
启动成功后,咱们浏览器访问http://localhost:8080,出现以下界面。spring
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
server: port: 7003 spring: application: name: sentinel-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848 sentinel: transport: dashboard: 127.0.0.1:8080
@SpringBootApplication public class SentinelApplication { public static void main(String[] args) { SpringApplication.run(SentinelApplication.class, args); } } @RestController class TestController{ @GetMapping("/test") public String test(){ return "hello! sentinel!"; } }
咱们请求几回这个接口后,打开sentinel控制台,就能够实时监控到这个sentinel-provider服务接口调用状况了。浏览器
咱们这里作一个简单的规则配置:并发
阀值类型:QPSapp
意思就是:该接口每秒最多容许进入两个请求。框架
点击新增后,在流控规则里发现了一条规则:分布式
如今,咱们继续请求3次这个接口。第三次响应的内容以下:ide
Blocked by Sentinel (flow limiting)
咱们打开控制台发现拒绝了一条请求。
不论是限流仍是降级,它都是按照某种规则进行的,下面具体介绍一下sentinel支持的几种规则。
流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时
对流量进行控制,以免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
资源名:惟一名称,默认是请求路径,可自定义
针对来源:指定对哪一个微服务进行限流,默认指default,意思是不区分来源,所有限制
阈值类型/单机阈值:
QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流
降级规则就是当知足什么条件时,对服务降级——即将请求转发到另外接口上,这个接口与业务无关,只是为了保证系统的完整性。
RT(平均响应时间) :当资源的平均响应时间超过阈值(以 ms 为单位)以后,资源进入准降级状态。若是接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,那么在接下的时间窗口(以 s 为单位)以内,就会对这个方法进行服务降级。
注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算做 4900 ms,若须要变动此上限能够经过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
异常比例:当资源的每秒异常总数占经过量的比值超过阈值以后,资源进入降级状态,即在接下的时间窗口(以 s 为单位)以内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0,1.0]。
热点规则容许将规则具体到参数上。
咱们用个例子来看看效果。
@GetMapping("/myTest") @SentinelResource("test3") public String test123(String name,String age){ return name + "----"+ age; }
结果显示,第一个参数被限流了,而第二个参数正常。
系统保护规则是从应用级别的入口流量进行控制,从单台机器的整体 Load、RT、入口 QPS 、CPU使用率和线程数五个维度监控应用数据,让系统尽量跑在最大吞吐量的同时保证系统总体的稳定性。
系统保护规则是应用总体维度的,而不是资源维度的,而且仅对入口流量 (进入应用的流量) 生效。
Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps minRt 计算得出。设定参考值通常是 CPU cores 2.5。
RT:当单台机器上全部入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
线程数:当单台机器上全部入口流量的并发线程数达到阈值即触发系统保护。
入口 QPS:当单台机器上全部入口流量的 QPS 达到阈值即触发系统保护。
不少时候,咱们须要根据调用来源来判断该次请求是否容许放行,这时候可使用 Sentinel 的来源问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否经过:
若配置白名单,则只有请求来源位于白名单内时才可经过;
流控应用:sentinel提供了RequestOriginParser来处理接口来源。
咱们运行abc来源的请求访问/test接口。
@Component class requestOrigin implements RequestOriginParser{ @Override public String parseOrigin(HttpServletRequest httpServletRequest) { String server = httpServletRequest.getParameter("server"); return server; } }
咱们请求http://localhost:7003/test?server=abc 和 http://localhost:7003/test?server=ab来分别看看效果。
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。
主要参数有如下几个
属性 | 做用 |
---|---|
value | 资源名称 |
entryType | entry类型,标记流量的方向,取值IN/OUT,默认是OUT |
blockHandler | 处理BlockException的函数名称,函数要求:1. 必须是 public;2.返回类型 参数与原方法一致;3. 默认需和原方法在同一个类中。若但愿使用其余类的函数,可配置blockHandlerClass ,并指定blockHandlerClass里面的方法。 |
blockHandlerClass | 存放blockHandler的类,对应的处理函数必须static修饰。 |
fallback | 1. 返回类型与原方法一致;2. 参数类型须要和原方法相匹配;3. 默认需和原方法在同一个类中。若但愿使用其余类的函数,可配置fallbackClass |
fallbackClass | 存放fallback的类。对应的处理函数必须static修饰。 |
defaultFallback | 若同时配置了 fallback 和 defaultFallback,以fallback为准。 |
exceptionsToIgnore | 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。 |
exceptionsToTrace | 须要trace的异常 |
@sentinelResource可结合blockHandler用于限流处理,结合fallback用于降级处理。具体规则可经过sentinel控制台配置,具体我就不演示了,在下一章内容中,我会分别演示限流和降级的应用。
public class MySentinelResource { @SentinelResource(value="message",blockHandler="blockHandler",fallback="fallback") public String message(String str){ if(StringUtils.isBlank(str)){ throw new RuntimeException(); } return str; } /** * 限流处理 * @param str * @param ex * @return */ public String blockHandler(String str, BlockedException ex){ return str + "--"+ ex; } /** * 降级处理 * @param str * @return */ public String fallback(String str){ return null; } }
gitee:https://gitee.com/zhixie/spring-cloud-alibaba-learning/tree/master/sentinel-server
github:https://github.com/binzh303/spring-cloud-alibaba-learning/tree/master/sentinel-server