高并发系统三大利器之限流
什么是限流?
限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等。
坐地铁上班的同学对于这张图片是不是都不会陌生。
基本上在上下班的早晚高峰我们就会发现进站的闸机会有一部分是关闭的。为什么地铁站会关闭一部分闸机呢?这就是为了限流。毕竟地铁站就那么大,可容纳的人数也就那么多。如果大家一股脑全部挤进地铁站是不是又会发生踩踏事件什么的。这是生活中的限流。还有我们去景区玩,景区的门票是不是也是固定的,每天就卖那么多张,卖完即止。限流是不是和我们的生活也息息相关。
为什么要限流?
开篇也有说到限流是为了保证系统的稳定运行。假设我们一个系统一小时之最多只能处理10000个请求,但是一小时流量突增10倍,这突增的流量我们如果不进行限制的话,任由它直接进入系统的话,是不是直接会把我们的系统弄瘫痪,就无法对外提供服务了。本人就曾经被这个所坑过,有一次把爬虫开关拦截的开关给关掉了,突然有一大波的爬虫流量进入系统中,我们也没有把这些爬虫请求进行拦截,然后一股脑的全部给转发到下游系统里面去了。下游系统直接就找上门来了,造成他们的服务发生大量的超时。比如地铁早高峰的时候我们如果不对地铁站进行限流的话,大家是不是都会往地铁站挤,然后再往地铁里面挤,挤不上都还要挤。会导致地铁门都关不上,然后地铁就开不走,会导致越来越多的人堵在地铁站。然后最后就会导致整条地铁线都阻塞了。上班就妥妥的迟到了(对于程序员说大多数应该是弹性制的所以也不存在迟到这一说法)。
限流操作有哪些?
拒绝服务
这个是最最简单粗暴的做法了,直接把请求直接拒绝掉。
比如早高峰坐地铁的时候,直接让进入1000个人,剩下多出来的人不让坐地铁了。直接把入站口给关闭了。
服务降级
将系统的所有功能服务进行一个分级,当系统出现问题,需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,这样可以释放出更多的资源供给核心功能的去用。
假设有一个功能新用户注册完,要给用户发送多少优惠券。这时候服务降级的话就可以直接把送券服务关掉,让服务快速响应,提高系统处理能力。
应用到早高峰坐地铁的时候比如在人民广场这个大站点,处理不过来了那么多人换乘,我们是不是可以直接地铁一号线在人民广场不停,直接到下一站在停,这时候经过人民广场换乘的人就少了。
延迟处理
把请求全部放入到队列中,真正处理的话,就从队列里面依次去取,这样的话流量比较大的情况可能会导致处理不及时,会有一定的延时。双十一零点我们付款的时候,去查询订单的状态是不是也会有一定的延时,不像在平时付完款订单状态就变成了付款状态。
特权处理
这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。我们去银行办理业务的时候是不是也会经常需要排队,但是是不是经常会VIP
用户、什么白金卡用户,直接不需要排队,直接一上来就可以办理业务,还优先处理这些人的业务。是不是特羡慕这些人,哎 羡慕也没办法谁叫人家有钱咧。
限流的实现方式?
计数器方法
这是最简单的限流算法了,系统里面维护一个计数器,来一个请求就加1,请求处理完成就减1,当计数器大于指定的阈值,就拒绝新的请求。是通过全局的总求数于设置的阈值来达到限流的目的。通常应用在池化技术上面比如:数据库连接池、线程池等中应用。这种方式的话限流不是平均速率的。扛不住突增的流量。
漏桶算法
我们可以看到水是可以持续流入漏桶里面的,底部也是匀速的流出,如果流入的速率大于底部流出的速率,以及漏桶的水超过桶的大小就会发生益出。请求一经过漏桶的过滤,不管你请求有多少,速率有多快,我反正就这么个速度处理。我们平时坐地铁的时候是不是也是这样,不管你乘客有多少,反正就是隔5min发一趟车。那早高峰的时候你5min钟一趟车根本就不够用啊,上班的人太多啊,你需要加快速度处理啊,所以可能早高峰改为3min一趟,动态调整速率。
令牌桶
看图的话是不是令牌桶和漏桶都差不多,只不过令牌桶新增了一个匀速生产令牌的中间人以恒定的速度往桶里面放令牌,如果令牌的数量超过里桶的限制的话,令牌就会溢出,这时候就直接舍弃多余的令牌。每个请求过来必须拿到桶里面拿到了令牌才允许请求(拿令牌的速度是不限制的,这就意味着如果瞬间有大量的流量请求进来,可以短时间内拿到大量的令牌),拿不到令牌的话直接拒绝。这个令牌桶的思想是不是跟我们java里面的Semaphore 有点类似。Semaphore
是拿信号量,用完了就还回去。但是令牌桶的话,不需要还回去,因为令牌会定时的补充。令牌桶算法我们可以通过Google开源的guava包创建一个令牌桶算法的限流器。
总结
- 以上粗略的介绍了几种单机的限流思想,大家可以根据这个思想然后去实现各种各样的限流组件。
- 我们的限流算法每个里面是不是都一个阈值,这个阈值设置为多少是不是比较难。
阈值设置过大的话,服务可能扛不住,阈值设置小了会把用户请求给误杀,资源没有得到最大的一个利用。
分布式限流的话,以后有机会再讲。
结束
由于自己才疏学浅,难免会有纰漏,假如你发现了错误的地方,还望留言给我指出来,我会对其加以修正。
如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。
感谢您的阅读,十分欢迎并感谢您的关注。
版权声明: 本文为 InfoQ 作者【java金融】的原创文章。
原文链接:【http://xie.infoq.cn/article/af55da344ad9c40bfd9c50aed】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论