限流场景&限流方案的一些思考

限流场景

  1. 保护系统资源:限流可用于保护系统资源,防止系统被过度请求而导致资源耗尽或系统崩溃。例如,限制对数据库、缓存、消息队列等关键资源的访问速率,以确保系统的稳定性和可用性。

  2. 防止恶意攻击:限流可用于防止恶意攻击和恶意请求,如暴力破解、DDoS 攻击等。通过限制来自单个 IP 地址或单个用户的请求速率,可以有效地减轻攻击的影响,并保护系统的安全。

  3. 流量控制:限流可用于控制系统的流量,防止流量突增而导致系统负载过高。例如,限制某个 API 接口或服务的请求速率,以确保系统能够处理流量峰值,避免系统性能下降或服务不可用。

  4. 平滑流量:限流可用于平滑流量,防止突发流量对系统造成冲击。通过限制请求速率,可以平滑流量的到达时间,减少系统负载的波动,提高系统的稳定性和可靠性。

  5. 保护第三方服务:限流可用于保护对第三方服务的调用,防止对第三方服务造成过度压力。例如,限制对外部 API 的请求速率,以确保系统能够遵守第三方服务的使用规范,避免被封禁或受到惩罚。

常用限流算法

  1. 令牌桶算法

    • 基于令牌桶实现的限流算法。
    • 每秒生成一定数量的令牌,请求需要获取令牌才能被处理。
    • 令牌桶算法可以应对突发流量。
  2. 漏桶算法

    • 将访问请求的数据包放入“漏桶”中。
    • 以恒定速率处理请求,保证稳定性。

令牌桶算法的理解

系统以恒定速率向桶中放入令牌。如果请求(request)需要处理,必须先从桶中获取一个令牌。当桶中没有令牌时,拒绝请求(request)。

漏桶算法的理解

所有的请求(request)缓冲至桶内,系统以恒定的速率处理请求(request),当请求(request)的量累积至溢出桶外,拒绝请求(request)。

需要更平滑的流量控制,令牌桶算法可能更适合;如果你需要严格的速率控制,漏桶算法可能更合适。

由于令牌桶允许突发流量在阈值范围内激增,因此个人认为它的适用性更为广泛。

限流常用方案

  • Guava RateLimiter: Guava 提供的限流类库,简单易用,支持多种限流模式。
  • Java 9 java.util.concurrent.RateLimiter: Java 9 提供的限流类库,与 Guava RateLimiter 类似,但性能更高。(要求JDK版本必须9以上)
  • Redis: Redis 可以使用 Lua 脚本实现令牌桶限流,支持分布式限流。
  • Alibaba的Sentinel组件自带限流功能,基于滑动窗口算法实现,支持多种策略。

值得注意的是:将限流措施写在接口处时,流量已经抵达了系统内,才会进行限流判断。这种做法有时候可能会导致系统过载或不稳定性,尤其是在高流量或突发流量的情况下。

为了更有效地保护系统的稳定性,通常建议在流量的入口处或者在系统的边缘进行限流,例如在外部的反向代理层(比如 Nginx)或者 API 网关(比如 Zuul、Kong 等)上实施限流措施。

                            +--------------+
                            |   客户端     |
                            +--------------+
                                   |
                                   v
                            +--------------+
                            | 反向代理层  |
                            +--------------+
                                   |
                                   v
                            +--------------+
                            |   网关层     |
                            +--------------+
                                   |
                 +------------- v -------------+
                 |                              |
                 |                              |
         +--------------+                +--------------+
         |  服务实例1  |                |  服务实例2  |
         +--------------+                +--------------+

 

限流的基准

比如一个获取短信验证码的接口,你往往需要细化限流的基准,不能因为一个恶意用户的超频请求触发限流,导致其他正常用户请求失败。

此处可以参考我的另一篇博客

无论使用何种方式实现限流,都要考虑触发限流后,是否会影响正常用户。

posted @ 2024-03-23 16:12  Ashe|||^_^  阅读(24)  评论(0编辑  收藏  举报