• 限流的几种方式


    先来描述一下什么是限流

      限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等。

    一般做接口限流主要是为了应对突发流量,避免突发流量拖垮服务。如下面一些场景就有可能发生突发流量

    1. 微博热搜
    2. 恶意刷单
    3. 恶意爬虫
    4. 促销活动
    5. 防止DOS攻击

    首先是计算器方式实现

    计数器又分固定窗口和滑动窗口

    固定窗口计数器:

      就是一个计算器,就是在一个时钟周期(该周期也是可以设置的)内,设定一个访问阈值(就是在刚刚设置的时钟周期内的并发量)。如果并发量超过访问阈值,则开始限流

      存在的问题
      限流不均匀,如下所示我们规定10S内至多10个访问量,但2S内实际上有20个访问量。

      出现流量尖峰。

      

    滑动窗口计数器:

      

    固定窗口计数器算法由于其存在的临界问题(尖峰问题),统计的精度过低,可能在时间窗口的重置节点处接收大量流量,为解决这个问题,我们引入了滑动窗口算法。

    如下图,我们规定访问阈值10,时钟周期是5秒,5秒内超过10次访问量开始限流。该思想就是在任何一个5S内都只有10次访问量。

    很明显,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

      缺点:

    1. 不能解决请求分布不均的问题,即无法平滑流量
    2. 实现更复杂,需要维护时间窗口,占用内存更多,计算时间复杂度也相应变大。

    令牌算法:

      按照固定的速率往漏斗里添加水,(核心思想是所有请求需要再令牌桶获取到令牌才可以处理, 同时有一个服务匀速的往令牌桶装令牌。可以满足一定的突发请求处理,如果超过令牌桶的请求,也会被拒绝)

      过程:

    1. 一直放令牌,如果令牌桶达到上限则丢弃令牌,假设每秒放10个
    2. 可以应对一定程度的流量激增,如此时令牌桶有100个令牌,突然发生200次调用,则此时最开始的100次请求可以正常调用,后续的请求才会以10个/s的速率来调用

      优点:

    1.   解决了固定窗口流量尖峰的问题,确保在任意时刻,过去窗口时间内的请求不会超出阈值。
    2.   可以有效平滑流量,因为令牌桶的令牌是匀速放入的
    3.   相对滑动窗口更节省内存
    4.   适合电商抢购或者微博出现热点事件这种场景,因为在限流的同时可以应对一定的突发流量。如果采用漏桶那样的均匀速度处理请求的算法,在发生热点时间的时候,会造成大量的用户无法访问,         对用户体验的损害比较大。

    漏桶算法:

      就像一个漏斗,上面口大,下面口小,上面可以一直加很多水的水,但是下面小口的口径是固定的,只会有固定单位的水通过。而且上面水量过大,漏斗放不下  会溢出丢失

      将水和访问量换一下,就明白了  (核心思想就是请求收到后,会先进入漏斗,然后再按照限定速度请求服务,及可以达到限流的目的,也可以保证后台收到的请求都是平稳的。 但是也有一个缺点,就是突然流量的时候,会导致处理时间太长。当然流量更大的时候会被拒绝,这个是正常的)。

        优点:实现相对简单,可以限制服务请求速率,并且稳定在一个常速。

        缺点:对于特发流量处理效率过低,在没有到达服务器负载阈值,也只能串行处理请求。

        实现;限制队列的大小



  • 相关阅读:
    HDU 1229 还是A+B(A+B陶冶情操)
    WINDOWS API ——CREATETOOLHELP32SNAPSHOT——查找进程
    WinAPI: GetCurrentThread、GetCurrentThreadId、GetCurrentProcess、GetCurrentProcessId
    创建线程后马上CloseHandle(threadhandle)起什么作用
    CloseHandle(),TerminateThread(),ExitThread()的区别
    WinAPI: OpenProcess、GetExitCodeProcess、TerminateProcess (测试强制关闭 OICQ)
    GetVersion和GetVersionEx
    WinAPI: GetModuleFileName、GetModuleHandle
    C# 获取窗口句柄并且关闭应用程序
    IsWindow,findwindow
  • 原文地址:https://www.cnblogs.com/shuai666/p/15693545.html
Copyright © 2020-2023  润新知