科百科
当前位置: 首页 科技资讯

高并发的优化代码(高并发系统的限流算法与实现)

时间:2023-06-03 作者: 小编 阅读量: 1 栏目名: 科技资讯

固定时间窗口算法就是统计记录单位时间内进入系统或者某一接口的请求次数,在限定的次数内的请求则正常接收处理,超过次数的请求则拒绝掉或者改为异步处理等限流措施。所以固定时间窗口算法无法限制窗口间突发流量。只要窗口包括的所有格子的计数器总和超过限流上限,便会执行限流措施。令牌桶算法允许流量一定程度的突发。因此,令牌桶算法也被广泛使用。

更多内容,欢迎关注全菜工程师小辉~

开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。

  • 缓存:缓存的目的是提升系统访问速度和增大系统处理容量。
  • 降级:降级是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
  • 限流:限流的目的是通过对并发请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以进行拒绝服务、排队或等待、降级等处理。

限流是限制系统的输入和输出流量,以达到保护系统的目的,而限流的实现主要是依靠限流算法,限流算法主要有4种:

  1. 固定时间窗口算法(计数器)
  2. 滑动时间窗口算法
  3. 令牌桶算法
  4. 漏桶算法

1. 固定时间窗口算法

又称计数器算法。固定时间窗口算法就是统计记录单位时间内进入系统或者某一接口的请求次数,在限定的次数内的请求则正常接收处理,超过次数的请求则拒绝掉或者改为异步处理等限流措施。

时间窗口长度如果为1分钟,如图。

计数器算法

此算法在单机还是分布式环境下实现都非常简单,使用redis的incr原子自增性即可轻松实现。

单机伪代码如下。

class CounterDemo { public long timeStamp = getNowTime(); public int reqCount = 0; public final int limit = 100; // 时间窗口内最大请求数 public final long interval = 1000; // 时间窗口ms public boolean grant() { long now = getNowTime(); if (now < timeStampinterval) { // 在时间窗口内 reqCount; // 判断当前时间窗口内是否超过最大请求控制数 return reqCount <= limit; } else { timeStamp = now; // 超时后重置 reqCount = 1; return true; } }}

算法特点

  1. 实现简单。
  2. 时间窗口固定,每个窗口开始时计数为零,这样后面的请求不会受到之前的影响,做到了前后请求隔离。
  3. 因为两个时间窗口之间没有任何联系,所以调用者可以在一个时间窗口的结束到下一个时间窗口的开始这个非常短的时间段内发起两倍于阈值的请求。所以固定时间窗口算法无法限制窗口间突发流量。

2. 滑动时间窗口算法

滑动时间窗口算法其实是固定时间窗口算法的优化,主要是为了解决固定时间窗口算法无法限制窗口间突发流量的缺点。

上面的计数器的单位时间是1分钟,而在使用滑动时间窗口,可以把1分钟分成6格,每格时间长度是10s,每一格又各自管理一个计数器,单位时间用一个长度为60s的窗口描述。一个请求进入系统,对应的时间格子的计数器便会 1,而每过10s,这个窗口便会向右滑动一格。只要窗口包括的所有格子的计数器总和超过限流上限,便会执行限流措施。

滑动窗口算法

由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

算法特点

  1. 因为窗口顺延,所以可以抵御窗口间突发流量(对比固定时间窗口算法)。
  2. 假如限流10万次/小时,如果某个调用者在前10分钟调用了10万次那么他必须再等待1小时才能发起下一次正常请求。所以没有做到前后请求隔离。

阿里开源的Sentinel,采用的是滑动窗口算法进行限流,可以阅读相关代码,加深对滑动时间窗口算法的理解。

3. 漏桶算法(leaky bucket)

漏桶算法其实很简单,可以粗略的认为就是注水漏水过程,往桶中以一定速率流出水,以任意速率流入水,当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。这个从桶底流出去的水就是系统正常处理的请求,从旁边流出去的水就是系统拒绝掉的请求。

漏桶算法

单机伪代码如下。

class LeakyDemo { public long timeStamp = getNowTime(); public int capacity; // 桶的容量 public int rate; // 水漏出的速度 public int water; // 当前水量(当前累积请求数) public boolean grant() { long now = getNowTime(); water = max(0, water - (now - timeStamp) * rate); // 先执行漏水,计算剩余水量 timeStamp = now; if ((water1) < capacity) { // 尝试加水,并且水还未满 water= 1; return true; } else { // 水满,拒绝加水 return false; } }}

算法特点

  1. 因为流出的速度是一定的,可以抵御突发流量,做到更加平滑的限流,而且不允许流量突发。

4. 令牌桶算法(Token Bucket)

令牌桶算法是比较常见的限流算法之一,Google开源项目Guava中的RateLimiter使用的就是令牌桶算法。流程如下:

  1. 所有的请求在处理之前都需要拿到一个可用的令牌才会被处理。
  2. 根据限流大小,设置按照一定的速率往桶里添加令牌。
  3. 桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝。
  4. 请求到达后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除。

令牌桶算法

单机伪代码如下,分布式环境可以使用Redisson。

class TokenBucketDemo { public long timeStamp = getNowTime(); public int capacity; // 桶的容量 public int rate; // 令牌放入速度 public int tokens; // 当前令牌数量 public boolean grant() { long now = getNowTime(); // 先添加令牌 tokens = min(capacity, tokens(now - timeStamp) * rate); timeStamp = now; if (tokens < 1) { // 若桶中没有令牌,则拒绝 return false; } else { // 还有令牌,领取令牌 tokens -= 1; return true; } }}

算法特点

  1. 可以抵御突发流量,因为桶内的令牌数不会超过给定的最大值
  2. 可以做到更加平滑的限流,因为令牌是匀速放入的。
  3. 令牌桶算法允许流量一定程度的突发。(相比漏桶算法)

在时间点刷新的临界点上,只要剩余token足够,令牌桶算法会允许对应数量的请求通过,而后刷新时间因为token不足,流量也会被限制在外,这样就比较好的控制了瞬时流量。因此,令牌桶算法也被广泛使用。

更多内容,欢迎关注全菜工程师小辉~

,
    推荐阅读
  • 新鲜核桃怎么保存(核桃保存方法)

    下面更多详细答案一起来看看吧!新鲜核桃怎么保存可以把鲜核桃去掉绿色外壳后保留剩下的,稍微风干,分成小份放到保鲜袋中,密封好。核桃仁中含有锌、锰、铬等人体不可短少的微量元素。人体在变老过程中锌、锰含量日渐下降,铬有促进葡萄糖使用、胆固醇代谢和维护心血管的功用。

  • 油沙豆怎么吃功效好(油沙豆如何吃功效好)

    跟着小编一起来看一看吧!油沙豆怎么吃功效好油沙豆可以制作豆浆喝功效比较好。油沙豆营养成分非常高,含有可溶性纤维和多种氨基酸,并且不含胆固醇,而且镁的含量非常高,对于预防骨质疏松,心血管病等都有很好的效果,并且含有最基本氨基酸物质精氨酸也很适合儿童。直接用油豆沙打豆浆,不会破坏营养成分,功效会发挥的很好。

  • 奸臣是反派(奸臣太嚣张)

    说完,将手里的名册交给言萧。慎刑司向来以刑法严苛和手段残忍著称,在言萧安插自己的徒弟言司命进入慎刑司以来,又多了一个屈打成招的特性。如世人所言,言萧的的确确是个大奸臣,此刻我也如此认定。言萧命人寻找大夫,情急之下抓错了混入一两个也是极有可能的事。身后的一行人投来鄙夷的神色,求奸臣饶恕,向来都是一件可耻的事情,况且,还是像言萧这样的大奸臣。

  • 宪法是一部好宪法(我国现行宪法是一部好宪法)

    30多年来的实践充分表明,我国宪法有力坚持了中国共产党领导,有力保障了人民当家作主,有力促进了改革开放和社会主义现代化建设,有力推动了社会主义法治国家建设进程,有力维护了国家统一、民族团结、社会稳定。依法治国是党领导人民治理国家的基本方略,法治是治国理政的基本方式。宪法具有最高的法律地位、法律权威、法律效力,具有根本性、全局性、稳定性、长期性。

  • 一阴一阳之谓道继之者善也成之者性也意思(一阴一阳之谓道继之者善也成之者性也出处)

    富有之谓大业,日新之谓盛德。变通配四时,阴阳之义配日月,易简之善配至德。圣人有以见天下之赜,而拟诸其形容,象其物宜,是故谓之象。拟之而后言,议之而后动,拟议以成其变化。

  • 林允儿简介(林允儿的介绍)

    林允儿简介林允儿,1990年5月30日出生于韩国首尔永登浦区,韩国女歌手、演员、主持人,女子演唱团体少女时代成员。2002年,林允儿参加韩国SM娱乐有限公司的选秀而进入SM公司成为旗下练习生。2007年8月5日,以演唱团体少女时代成员身份正式出道。2008年,主演情感剧《你是我的命运》获得第45届韩国百想艺术大赏电视剧类最佳新人女演员奖和人气女演员奖。2010年,加入SBS电视台综艺节目《家族诞生2》并担任固定主持人。

  • 横多音字组词(横怎么组词)

    以下内容大家不妨参考一二希望能帮到您!横多音字组词才华横溢[cáihuáhéngyì]横溢:充分显露。指才华充分显露出来。尸横遍野[shīhéngbiànyě]横:纵横杂乱。横冲直撞[héngchōngzhízhuàng]形容乱冲乱撞或蛮不讲理。横行无忌[héngxíngwújì]倚仗暴力,无所顾忌地干坏事。突然降临的、无法防范的灾祸。也作“飞灾横祸”。专横跋扈[zhuānhèngbáhù]专横:专断蛮横。形容任意妄为、不讲理。

  • 小孩吃的小米粥的8种做法养胃(宝宝喝后胃肠好)

    宝宝喝后胃肠好​苹果和山药,放在一起来煮粥口感不错,宝宝爱喝,常喝脾胃好简单一碗粥,宝宝喝后胃肠好,一种水果一种菜,加点大火煮起来宝宝们经常因为摄入过量的油腻食物,家人没有好好的把控住,而适成胃肠不舒服,或者脾胃不。

  • 洞庭湖属于湖南还是属于湖北(湖南湖北的湖指洞庭湖)

    事实上,省名也有不同的历史文化积淀和象征意义。正式成立南越国,定都番禺。当时交通便利,人口众多,是岭南地区的中心城市。赵佗接受了汉高祖赐给的南越王尹寿,投降汉朝,显然成为汉朝的附庸国。其后,唐初,岭南地区为更好地管理,先后在广州、贵州、荣州、永州、安南等地设立了五座总督府,又称岭南武馆。655年后,吴府隶属于广州首府吴府景略,由广州第二令兼任。宋廷将岭南定为广南路。

  • 官宣梅西离开巴萨(曝梅西可以随时离开巴萨)

    这起风波,目前只有家人支持着梅西,可以说,家庭始终是梅西最温暖港湾。梅西已经和巴萨多次续约,他的合同中有特殊条款,每个赛季末,他可以单方面解约离开,这意味着,梅西随时可以离开诺坎普。接下来,巴萨危机该何去何从,球迷们只能观望了,西媒指出,阿比达尔可能走人。但显然,巴萨真正应该承担责任的是巴托梅乌。