限流能够认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。通常来讲系统的吞吐量是能够被测算的,为了保证系统的稳定运行,一旦达到的须要限制的阈值,就须要限制流量并采起一些措施以完成限制流量的目的。好比:延迟处理,拒绝处理,或者部分拒绝处理等等。java
坐地铁上班的同窗对于这张图片是否是都不会陌生。
基本上在上下班的迟早高峰咱们就会发现进站的闸机会有一部分是关闭的。为何地铁站会关闭一部分闸机呢?这就是为了限流。毕竟地铁站就那么大,可容纳的人数也就那么多。若是你们一股脑所有挤进地铁站是否是又会发生踩踏事件什么的。这是生活中的限流。还有咱们去景区玩,景区的门票是否是也是固定的,天天就卖那么多张,卖完即止。限流是否是和咱们的生活也息息相关。程序员
开篇也有说到限流是为了保证系统的稳定运行。假设咱们一个系统一小时之最多只能处理10000个请求,可是一小时流量突增10倍,这突增的流量咱们若是不进行限制的话,任由它直接进入系统的话,是否是直接会把咱们的系统弄瘫痪,就没法对外提供服务了。本人就曾经被这个所坑过,有一次把爬虫开关拦截的开关给关掉了,忽然有一大波的爬虫流量进入系统中,咱们也没有把这些爬虫请求进行拦截,而后一股脑的所有给转发到下游系统里面去了。下游系统直接就找上门来了,形成他们的服务发生大量的超时。好比地铁早高峰的时候咱们若是不对地铁站进行限流的话,你们是否是都会往地铁站挤,而后再往地铁里面挤,挤不上都还要挤。会致使地铁门都关不上,而后地铁就开不走,会致使愈来愈多的人堵在地铁站。而后最后就会致使整条地铁线都阻塞了。上班就妥妥的迟到了(对于程序员说大多数应该是弹性制的因此也不存在迟到这一说法)。算法
这个是最最简单粗暴的作法了,直接把请求直接拒绝掉。
好比早高峰坐地铁的时候,直接让进入1000我的,剩下多出来的人不让坐地铁了。直接把入站口给关闭了。数据库
将系统的全部功能服务进行一个分级,当系统出现问题,须要紧急限流时,可将不是那么重要的功能进行降级处理,中止服务,这样能够释放出更多的资源供给核心功能的去用。
假设有一个功能新用户注册完,要给用户发送多少优惠券。这时候服务降级的话就能够直接把送券服务关掉,让服务快速响应,提升系统处理能力。
应用到早高峰坐地铁的时候好比在人民广场这个大站点,处理不过来了那么多人换乘,咱们是否是能够直接地铁一号线在人民广场不停,直接到下一站在停,这时候通过人民广场换乘的人就少多了。分布式
把请求所有放入到队列中,真正处理的话,就从队列里面依次去取,这样的话流量比较大的状况可能会致使处理不及时,会有必定的延时。双十一零点咱们付款的时候,去查询订单的状态是否是也会有必定的延时,不像在平时付完款订单状态就变成了付款状态。ide
这个模式须要将用户进行分类,经过预设的分类,让系统优先处理须要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。咱们去银行办理业务的时候是否是也会常常须要排队,可是是否是常常会VIP用户、什么白金卡用户,直接不须要排队,直接一上来就能够办理业务,还优先处理这些人的业务。是否是特羡慕这些人,哎 羡慕也没办法谁叫人家有钱咧。线程
这是最简单的限流算法了,系统里面维护一个计数器,来一个请求就加1,请求处理完成就减1,当计数器大于指定的阈值,就拒绝新的请求。是经过全局的总求数于设置的阈值来达到限流的目的。一般应用在池化技术上面好比:数据库链接池、线程池等中应用。这种方式的话限流不是平均速率的。扛不住突增的流量。code
咱们能够看到水是能够持续流入漏桶里面的,底部也是匀速的流出,若是流入的速率大于底部流出的速率,以及漏桶的水超过桶的大小就会发生益出。请求一通过漏桶的过滤,无论你请求有多少,速率有多快,我反正就这么个速度处理。咱们平时坐地铁的时候是否是也是这样,无论你乘客有多少,反正就是隔5min发一趟车。那早高峰的时候你5min钟一趟车根本就不够用啊,上班的人太多啊,你须要加快速度处理啊,因此可能早高峰改成3min一趟,动态调整速率。blog
看图的话是否是令牌桶和漏桶都差很少,只不过令牌桶新增了一个匀速生产令牌的中间人以恒定的速度往桶里面放令牌,若是令牌的数量超过里桶的限制的话,令牌就会溢出,这时候就直接舍弃多余的令牌。每一个请求过来必须拿到桶里面拿到了令牌才容许请求(拿令牌的速度是不限制的,这就意味着若是瞬间有大量的流量请求进来,能够短期内拿到大量的令牌),拿不到令牌的话直接拒绝。这个令牌桶的思想是否是跟咱们java里面的Semaphore 有点相似。Semaphore
是拿信号量,用完了就还回去。可是令牌桶的话,不须要还回去,由于令牌会定时的补充。令牌桶算法咱们能够经过Google开源的guava包建立一个令牌桶算法的限流器。队列