异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。
下面演示一个平均响应时间熔断,创建一个接口,如下:
@RestController @RequestMapping("/sentinel/provider") @Slf4j public class FlowLimitController { @GetMapping("/test") public String test() throws InterruptedException { //休眠3秒钟 Thread.sleep(3000); log.info("收到一条消息----test"); return "接收到一条消息--------"; } }在控台为这个接口设置平均响应时间为200毫秒,时间窗口为1秒,大致意思:平均的响应时间大于200毫秒之后,在接下来的1秒时间内将会直接熔断,如下图:
使用Jmeter开启10个线程循环跑,然后在浏览器中访问这个接口,返回结果如下图:
为什么呢?由于的接口中休眠了3秒,平均响应时间肯定大于200毫秒,因此直接被熔断了。
注意:这里熔断后直接返回默认的信息,后面会介绍如何定制熔断返回信息。
9、热点参数如何限流?顾名思义:热点就是经常访问的数据,很多时候肯定是希望统计某个访问频次Top K数据并对其进行限流。
比如秒杀系统中的商品ID,对于热点商品那一瞬间的并发量是非常可怕的,因此必须要对其进行限流。
Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。
注意:热点参数限流只针对QPS。
官方文档:https://github.com/alibaba/Sentinel/wiki/热点参数限流
概念理解了,来看下sentinel控制台如何设置热点参数限流,如下图:
规则对应得源码在com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule这个类中,各种属性含义如下图:
规则都懂了,下面我们通过实战来演示一下热点参数到底是如何限流的。
注意:热点参数限流只作用于八大基本类型。
1、创建一个资源现在先创建一个service,用@SentinelResource这个注解定义一个资源,这个注解后续将会详细介绍,先忽略,代码如下:
@Service @Slf4j public class FlowServiceImpl implements FlowService { /** * @SentinelResource的value属性指定了资源名,一定要唯一 * blockHandler属性指定了兜底方法 */ @Override @SentinelResource(value = "OrderQuery",blockHandler = "handlerQuery") public String query(String p1, String p2) { log.info("查询商品,p1:{},p2:{}",p1,p2); return "查询商品:success"; } /** * 对应得兜底方法,一旦被限流将会调用这个方法来处理 */ public String handlerQuery(@RequestParam(value = "p1",required = false) String p1, @RequestParam(value = "p2",required = false)String p2, BlockException exception){ log.info("查询商品,p1:{},p2:{}",p1,p2); return "查询商品:熔断了......"; } }上述代码什么意思呢?如下:
如果query这个接口没有被限流则返回:查询商品:success
如果query这个接口被限流了,则进入了兜底方法handlerQuery方法,返回:查询商品:熔断了......
2、创建controller接口下面创建一个controller进行测试,代码如下:
@RestController @RequestMapping("/sentinel/provider") @Slf4j public class FlowLimitController { @Autowired private FlowService flowService; @GetMapping("/order/query") public String query(@RequestParam(value = "p1",required = false) String p1, @RequestParam(value = "p2",required = false)String p2){ return flowService.query(p1,p2); } }可以看到接口中有两个参数,分别是p1、p2。
3、添加热点参数限流规则在sentinel控制台点击热点规则->新增热点限流规则,添加如下图规则: