Sentinel基本概念
Sentinel核心作用就是流量控制,针对请求链路中的每一个环节做流量控制,从而保护系统。
一个客户端发起一个请求,先到反向代理服务器,然后到应用网关,网关再将请求路由到应用模块,然后模块内部调用需要的下游api服务来获取返回结果。
要实现流量控制,有两个核心因素:资源、规则。
资源:资源是指被Sentinel保护的目标对象,大部分情况,使用方法签名,URL,服务名称作为资源名来标识资源。
规则:针对目标资源所设定的流控规则,包括流量控制规则、熔断降级规则、系统保护规则,所有规则可以实时动态调整。
实际应用中,请求数量是随机且不可控的,而系统处理能力是有限的,所以我们需要根据系统处理能力对流量进行控制。Sentinel的核心作用,就是针对目标资源使用对应的规则把随机的请求调整成合适的形状。
流量控制通常有以下维度:
- 资源的调用关系:例如资源的调用链路,资源间的关系
- 运行指标:例如QPS、线程池、系统负载等;
- 控制效果:例如直接限流、冷启动、排队等;
常见限流算法
计数器限流
设置一个计数器counter,每次请求计数器加1,在一定时间内统计访问数量,如果超过限流数量则拒绝;如果当前请求与第一次请求时间超过了规定的频率,则计数器重新开始计数。
缺陷:计数器限流存在临界值问题,在临界点处,可能请求数量会超过限流数量。
滑动窗口限流
通过滑动窗口可以解决计数器限流的临界值问题
可以通过下面网址演示:Selective Repeat Protocol (pearsoncmg.com)
发送和接收方都维护一个数据帧的序列,这个序列称之为窗口。通过控制窗口大小来控制发送速度,从而起限流效果。如下图所示,0号数据帧已经发送并且收到Ack,1、2、3、4号已发送还未收到Ack,而5号数据帧则是等待发送,可以看到发送端窗口大小为5。如果接下来1、2、3、4号收到Ack,窗口会向右滑动4格,那么6、7、8、9号也可以发送。
漏桶限流
在桶上开一个孔,不断的往桶里注水,注水的速度是不确定的,但是出水的速度是固定的。如果桶满了,则会触发流量异常,有两种常见的处理方式:
- 暂时拦截注水口水流注入,等桶中一部分水流出后,再放开注水口注入。
- 超过桶容量的水溢出抛弃。
MQ就是一种漏桶行为,MQ类似一个桶,生产者发送消息的速率是不可控的,但是消费端可以控制消费的速率。
特点:无论注水速率多大都没有影响,漏水速率是固定的
令牌桶限流
令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limit)中最常用的一种算法。令牌桶算法用来控制发送到网络上的数据的数目。
令牌桶是一个存放固定容量令牌的桶,系统会以固定的速度生成令牌并添加到桶里;可以把令牌桶想象成一个缓冲区(可以用队列来实现),当缓冲区填满的时候,新生成的令牌会被扔掉。令牌桶算法由三部分组成:令牌流,数据流,令牌桶。令牌桶算法有两个重要的变量:
- rate:生成令牌的速度;比如rate=2,则每秒钟生成2个令牌。
- burst:令牌桶的大小;比如burst=10,则代表令牌桶最大只能容纳10个令牌。
数据流是进入系统的请求流量,如果每秒钟调用2次http请求,则代表速率是2次/s。
- 数据流速率 = 令牌流速率:每个请求都有对应的令牌,无延迟通过队列。
- 数据流速率 < 令牌流速率:请求只会消耗部分令牌,剩余令牌会在桶里累积直到桶满,可以应对突发情况大量请求。
- 数据流速率 > 令牌流速率:令牌不够请求消耗,可能会发生丢包或者拒绝响应。
特点:令牌可以累积,可以应对临时突发事件的大量请求。
熔断机制
指标
维度
异常数:比如10s内,100个请求,50个失败
慢调用比例:比如10s内,100个请求,有多少个请求的响应时间超过了多少s
异常比例:比如100个请求,50%失败
DegradeRule rule = new DegradeRule();
// 熔断模式:慢调用比例
rule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());