什么是服务限流?
当服务系统资源不够,无法承载大量请求时,需要对系统按照一定的规则进行流量限
为什么需要服务限流?
系统承载的访问量是有限的,如果不做流量控制,会导致系统资源占满,服务超时,在微服务体系中就有可能引起服务瘫痪和整体不可用的现象
sentinel是什么?
sentinel是面向分布式服务架构的轻量级的流量控制产品
sentinel的基本发展过程:
2012年 sentinel诞生于阿里巴巴, 2013-2018年 sentinel在集团内部快速发展,覆盖了大部分的应用场景, 2018年 sentinel开源
sentinel 能做什么?
流量控制
熔断
降级
系统负载保护
本文章主要介绍利用sentinel来实现流控的能力。
qps限流方式
集群限流(集群均摊模式)
集群限流,在sentinel中,有两种身份,
在sentinel的集群流控上,又分为两种情况

http://mutou.qklchain.com/share/bZlefF.png 
http://mutou.qklchain.com/share/tQWSfp.png 相比于集体均摊的限流模式,单机均摊模式,无需单独部署tokenserver,无需和tokenserver保持通讯,所以减少了请求的时间损耗,不过实际情况是到每台机器的流量不是均匀的,所以单机流量无法像集群均摊模式一样准确的限制集群流量,导致总量没到的情况下,某台机器就开始了限流
单机均摊模式,限制某个资源在单台服务器上的qps,此方式的tokenserver可以和应用进程同时部署,比如现在有4个client连接到了sentinel server,每个client的均摊阈值时10,那么集体均摊的限流控制是4*10=40个,如下图 集体均摊模式,限制某个资源的整体qps,此时的tokenserver需要单独部署,比如可以配置集群qps限流控制为40,此时每次的qps请求都要经过tokenserver进行验证,如下图:
tokenclient 用于向tokenServer请求token tokenServer负责处理tokenclient的请求,并根据配置的集群信息判断是否需要发放token
并发数限流方式
线程池限流:
在sentinel中,主要基于线程池技术来实现并发数限流,针对于某个资源,会隔离出一些线程,sentinel会控制当前资源的使用线程数,当超过请求时给与拒绝或者等待,直到堆积的线程处理完成线程池限流方式的优点是隔离线较强
优点:资源线程相互隔离,减少了依赖服务之间的互相影响
缺点:线程数量过多,会导致线程上下文的overhead比较大,所以尤其会对低延迟的服务禅城一定的影响

并发数(信号量)限流:
基于线程数限流,则不需要创建和管理线程池,而是简单的统计当前资源的上下文的线程数据,如果超过阈值,则进行拒绝处理
sentinel是如何实现qps限流的?
sentinel实现限流的核心是一套责任链模式
ProcessorSlot 是一个父类,所有的责任链和SLot都实现了ProcessorSlot,责任链的entry会一次执行责任链的各个slot
在sentinel我们常用的slot有下面集中:
StatisticSlot(StaticsticSlot主要负责统计资源调用情况) flowSlot(主要负责基于统计资源做限流规则验证)
sentinel的滑动窗口实现基于leapArray,核心关注几个参数
时间窗口长度(ms windowLengthMs)
窗口长度(sampleCount)
时间间隔(intervalInMs)
窗口开始时间 = 当前时间(ms)-当前时间(ms)%时间窗口长度(ms)
比如:
intervallInMs=1000ms, sampleCount=2, 那么windowLengthMs=500ms
intervallInMs=60s,sampleCount=60,那么windowLengthMs=1s
获取当前时间戳下的时间id的方法
long timeId = time / windowLength
int idx = (int)(timeId % array.length());
其中time为当前时间,array是时间窗口数量
如果获取到的时间窗口自为空,则新建时间窗口 如果获取到的时间窗口非空,且时间窗口开始时间=计算的开始时间,说明当前时间正好在这个时间窗口里,直接返回当前窗口。 如果获取到的时间窗口非空,且时间窗口的开始时间小于我们计算的开始时间,说明时间窗口已经过期(距离上次获取时间窗口已经过去比较久的场景),需要更新时间窗口(CAS加锁操作),将时间窗口的开始时间设为计算出来的开始时间,将时间窗口里的计数器重置为0,
时间窗口内部的计数器,主要记录以下信息
通过计数 阻塞计数 异常计数 成功计数 响应rt
以上几个数都是在sentinel StaticsicSlot中的entry和exist函数中记录
而flowSlot用于做两件事情
获取资源对应的限流规则 根据限流规则判断是否被限流
如果对改文章内容某些细节不了解,可以继续阅读sentinel的源代码,或者直接联系 老k聊架构




