QPS的概念:每秒钟的请求个数
流控规则:就是对流量进行控制,也是就对访问的请求进行控制
排队等待:
图1
如图1所示:
设置阈值是10,代表1秒钟通过10个请求,每个请求最大的等待时间是1000/10=100ms(如果实际qps小于所设置的值,则不会被触发),超时时间=2s,代表每个请求的最长等待时间为2s(请求排队等待,每个请求又有预计通过的时间,如果预计通过的时间大于所设置的2秒,这个请求就会被拒绝掉)。这里所指的排队等待,指的是这个10个请求,匀速排队请求。这里的意义主要在于,不让请求一下子执行,以防冲垮系统。(如果要使请求尽量都通过,而且排队等待通过,就要将超时时间设置长点)Warm Up:
图2
图3
如图2所示:
Warm Up方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。图中所示阈值是30,预热时长1秒,意思就是说系统的处理能力在1秒后才达到qps=30,之后才进行稳定请求,结果如图3所示。 快速失败:图4
当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。(注意要知道系统的处理能力,若阈值设置不当,会造成流量损失)3.降级规则:
降级规则,主要在于慢调用,这个比较不好理解,这个明白了,其它就好说
慢调用比例:
图5
如图5所示:
请求的最大响应时间>最大RT 视为慢调用 只有当单位统计时长内 1. 请求数>最小请求数 2. 慢调用比例阈值>比例阈值 这时服务就会被熔断,熔断时间为所设置的熔断时长,熔断时间过后,会进入恢复状态,若下一个请求是慢调用则再次熔断,不是慢调用则恢复。4. 授权规则:
图6
图7
图8
图9
白名单是通过,黑名单是拦截 这里有个比较重要的东西,黑白名单是通过资源名的请求来源来判断是否通过,而请求来源origin是通过调用方来注入的(这样感觉很不好,而且如果放在启动类来注入还无效) 调用方注入请求来源ContextUtil.enter(resourceName, origin)如图7所示是sentinel判断黑白名单是否通过的重要源码,如果调用方没有注入origin,则origin就会为空,然后就会直接通过致使黑名单拦截效果不会生效,而图8在控制层注入了来源,在图9里面黑名单的效果就有生效
5.关于集成方面
pom文件主要是引入下面4个,基本上够用
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-transport-simple-httpartifactId>
<version>${sentinel.version}version>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-apache-dubbo-adapterartifactId>
<version>${sentinel.version}version>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-annotation-aspectjartifactId>
<version>${sentinel.version}version>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-web-servletartifactId>
<version>${sentinel.version}version>
dependency>
在项目启动的jvm参数上加上下列参数
-Djava.net.preferIPv4Stack=true
-Dcsp.sentinel.api.port=用于请求实时数据的未被占用的端口
-Dcsp.sentinel.dashboard.server=控制台ip:控制台端口
-Dproject.name=项目名
springboot项目在配置bean的地方配置下面两个bean
/**
* sentinel 自定义资源名用的* @return
*/@Beanpublic SentinelResourceAspect sentinelResourceAspect() {return new SentinelResourceAspect();
}/**
* sentinel 与web适配* @return
*/@Beanpublic FilterRegistrationBean sentinelFilterRegistration() {FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();registration.setFilter(new CommonFilter());registration.addUrlPatterns("/*");registration.setName("sentinelFilter");registration.setOrder(2);return registration;
}
如果要自定义资源
就要在想自定义资源名的方法上加上以下注解
@SentinelResource(value = "资源名")
自定义资源的地方可以是项目中的任意一处方法
6.关于流控受限了,抛出给前端的信息方面
与web适配的,当流量受限时会抛给前端
Blocked by Sentinel (flow limiting)的信息
与dubbo适配的,当流量受限时会抛给前端
图10
用自定义资源名配置的,当流量受限时会抛出到控制台,需要自己全局捕捉异常处理,然后返回给前端
图11
图11是全局异常的处理,这样抛给前端的信息,如下图图12
图12
这里主要强调这一点是因为,如果不想被前端看到流量受限的信息,关于web适配和dubbo适配的,我们就需要去改一定的源码,而自定义资源名的可以在全局异常里面处理。关于web的,它的异常是在filter里面处理的,执行顺序是在ControllerAdvice 前,所以filter的异常无法抛出直接给全局异常