hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

罕见限流方案设计与完成

2019-11-18杂谈搜奇网23°c
A+ A-

高并发体系设想的3个利器:缓存、限流、降级,本文就限流相干算法,剖析其设想与完成。

从分布式角度来看,限流可分为分布式限流(比方基于Sentinel或许Redis的集群限流)和单机限流。从算法完成角度来看,限流算法可分为漏桶算法令牌桶算法滑动时刻窗口算法。下面重要剖析这3种限流算法和分布式限流完成计划。

漏桶算法

把要求比作是水,水来了都先放进桶里,并以恒定速度出水(处置惩罚要求),当水流量过大会致使桶溢出,即谢绝效劳。要求的最大处置惩罚速度也就是水从漏桶流出的速度。

基于漏桶(桶+恒定处置惩罚速度),可以起到对要求整流结果。漏桶算法可基于线程池来完成,线程池运用牢固容量的壅塞行列+牢固个数的处置惩罚线程来完成;最简朴且最常见的漏桶头脑的完成就是基于SynchronousQueue的线程池,其相称于一个空桶+牢固处置惩罚线程 : )。

注重:原生的漏桶算法以恒定速度出水(处置惩罚要求),然则现实场景中要求的处置惩罚耗时可以不相等,为了完成恒定速度,平常都是限制同时处置惩罚要求的最大线程数。

令牌桶算法

许多场景中,须要许可某种程度的突发要求,要求的最大速度也就是一切桶大小。这时刻漏桶算法就不适宜了,令牌桶算法更加合适。

令牌桶算法的道理是体系以恒定的速度发生令牌,然后把令牌放到令牌桶中,令牌桶有一个容量,当令牌桶满了的时刻,再向其中放令牌,那末过剩的令牌会被抛弃;当想要处置惩罚一个要求的时刻,须要从令牌桶中掏出一个令牌,假如此时令牌桶中没有令牌,那末则谢绝该要求。

令牌桶算法的一个完成计划是:起一个Timer线程以牢固频次往桶中放令牌,桶满时令牌溢出,营业线程在猎取令牌时直接从桶中猎取即可。该计划轻易明白,然则须要一个Timer线程,资本占用较重。

令牌桶算法另有一种完成计划不须要用Timer线程,这个典范完成就是Guava中的RateLimiterRateLimiter完成道理以下:

  1. startTick纪录RateLimiter初始化时的时刻戳(单元ns),后续nowMicros(当前时刻点)都是取(System.nanoTime()-startTick)/1000;
  2. nextFreeTicketMicros纪录下次可猎取令牌的最先时刻点,在RateLimiter初始化和猎取到令牌之后会举行更新;
  3. 假如nowMicros大于即是nextFreeTicketMicros,示意可以猎取令牌;假如nowMicros大于nextFreeTicketMicros,会盘算两者差值并除以放一个令牌的周期,然后赋值给storedPermits字段(示意当前桶中令牌数,注重不能凌驾桶容量);
  4. 然后storedPermits减去当前须要令牌数,假如此时要猎取令牌数大于storedPermits,那末会将nextFreeTicketMicros再今后推动(要猎取令牌 - storedPermits) * 放一个令牌的周期 的时刻。

更详细的步骤及代码完成可参考RateLimiter源码,这里不再赘述。

从步骤4可以看出,初始化一个RateLimiter.create(100),是可以实行rateLimiter.tryAcquire(200)的,只不多会将nextFreeTicketMicros再今后推动罢了。

滑动时刻窗口算法

滑动时刻窗口算法就是依据当前时刻猎取对应的时刻窗口,时刻窗口保留有流量相干的统计值,依据该统计值推断是不是触发流控。

平常来说,时刻窗口可以轮回复用,在复用时从新初始化即可,详细完成可参考sentinel的滑动窗口完成。滑动时刻窗口可以支撑的瞬时流量最大可为该窗口上限,而令牌桶算法可以支撑的瞬时流量最大为桶大小;注重,滑动时刻窗口算法中猎取token数目一次最大不能凌驾窗口上限,而RateLimiter完成的令牌桶可以支撑一次猎取凌驾桶大小的token。

分布式限流

上述所说的几种限流都是单台机械上的限流算法,有些场景下我们还须要分布式限流,一种是基于Redis做分布式限流,另一种类似于Sentinel分布式限流。

Sentinel

Sentinel分布式限流是启动一个token server效劳器,其他sentinel client端就是token client端,当作限流操纵时,从token server猎取token,猎取胜利示意未触发限流;不然示意触发了限流;通讯出现异常,可设置降级走当地Sentinel限流机制。分布式限流文档:Sentinel集群流控

sentinel的分布式限流是token client挪用以下要领到效劳端猎取token,相称因而每次都邑猎取acquireCount个token:

//猎取令牌Token, 参数划定规矩Id,猎取令牌数,优先级 
TokenResult requestToken(Long ruleId, int acquireCount, boolean prioritized); 

基于Redis限流

基于Redis做限流操纵,运用lua剧本保证敕令原子性,比方qps设置为10,假如key不存在,就设置key逾期时刻1s,value=1;假如value小于10,则自增value;value到达10触发流控。示例lua代码以下:

local key = "rate.limit:" .. KEYS[1]
local limit = tonumber(ARGV[1])
local expire_time = ARGV[2]

local is_exists = redis.call("EXISTS", key)
if is_exists == 1 then
    if redis.call("INCR", key) > limit then
        return 0
    else
        return 1
    end
else
    redis.call("SET", key, 1)
    redis.call("EXPIRE", key, expire_time)
    return 1
end

经常使用的限流算法有漏桶、令牌桶和滑动窗口,依据详细场景可选择差别限流算法;假如须要集群限流,可选用Sentinel或许基于Redis做分布式限流。

关于Sentinel,预计挺多小伙伴还不晓得Sentinel是个什么东东,Sentinel是一个以流量为切入点,从流量掌握、熔断降级、体系负载庇护等多个维度庇护效劳的稳定性的框架。github地点为:https://github.com/alibaba/Sentinel。

笔者整理了一份《Sentinel不完全指南》,须要的小伙伴可以关注「TopCoder」民众号发送 sentinel来猎取,《Sentinel不完全指南》和Sentinel官方文档,两者互为补充,结合起来进修Sentinel结果更好呦 : )

迎接小伙伴关注【TopCoder】浏览更多出色好文。

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
罕见限流方案设计与完成

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282272.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>