聊聊限流及及常用解决方案

聊聊限流及及常用解决方案
最新回答
甜警司

2023-09-20 07:16:44

限流是通过控制单位时间内的资源访问量或连接数,防止系统过载的核心技术手段,其核心维度包括时间窗口(如每秒/分钟)和资源限制(如最大请求数、连接数)。常用限流规则涵盖QPS/连接数控制、传输速率限制、黑白名单机制及分布式环境下的全局限流,算法层面则以令牌桶、漏桶和滑动窗口为主。

一、限流的核心规则与场景
  1. QPS和连接数控制

    基于IP或服务器的多维度限制,例如:单个IP每秒请求≤10次、连接数≤5,单台服务器QPS≤1000、连接数≤200。

    分布式场景下可扩展至服务器组或机房级别,如限制整个集群的QPS上限。

  2. 传输速率限制

    针对下载、API调用等场景,按用户组或标签差异化限速。例如:普通用户下载速度100KB/s,会员10MB/s。

  3. 黑白名单机制

    黑名单:动态封禁异常IP(如机器人、攻击流量),例如爬虫需频繁更换IP以规避封禁。

    白名单:允许特定用户(如企业大客户)绕过限流规则,保障关键业务。

  4. 分布式限流

    将集群内所有服务器视为整体,通过中心化组件(如Redis)统一存储限流数据。

    主流方案:

    网关层限流:在流量入口(如Nginx、Spring Cloud Gateway)统一控制。

    中间件限流:利用Redis+Lua脚本实现全局计数器。

    Sentinel组件:Spring Cloud生态中的分布式限流工具,支持熔断降级。

二、限流算法详解
  1. 令牌桶算法

    原理:以固定速率生成令牌,请求需获取令牌才能执行。桶容量有限,超量令牌丢弃。

    特点

    支持突发流量:桶内预存令牌可应对短时高并发。

    可选缓冲队列:未获取令牌的请求排队等待,队列满则丢弃。

    应用场景:需要兼顾平滑流量与突发响应的系统,如API网关。

  2. 漏桶算法

    原理:请求以恒定速率处理,超出部分排队或丢弃。

    特点

    强制平滑流量:无论输入速率如何,输出速率恒定。

    无突发能力:与令牌桶相反,适合对稳定性要求极高的场景。

    应用场景:实时音视频传输、金融交易系统。

  3. 滑动窗口算法

    原理:将时间轴划分为多个窗口,动态计算当前窗口内的请求数。

    特点

    窗口跨度越长,限流效果越平滑。

    避免短时流量波动导致误限流。

    应用场景:需要精确控制单位时间请求量的接口,如秒杀活动。

三、常用限流方案与实现
  1. 合法性验证限流

    通过验证码、IP黑名单等手段拦截恶意请求,适用于防止爬虫或攻击。

  2. Guava RateLimiter

    适用场景:单机限流(如单台服务器的接口调用控制)。

    局限:无法跨JVM或服务器集群协同限流。

    示例:限制单个服务器每秒处理100个请求。

  3. Nginx限流

    控制速率

    limit_req_zone:限制单位时间请求数(如2r/s)。

    burst:允许突发请求(如burst=4)。

    控制并发数

    limit_conn_zone:限制单个IP或服务器的并发连接数(如limit_conn perip 10)。

    优势:高性能,适合作为网关层的第一道防线。

  4. Redis+Lua中间件限流

    原理:利用Redis的原子操作和Lua脚本实现分布式计数器。

    优势:支持集群环境,可灵活设置时间窗口(如每秒100请求)。

    示例

    local key = KEYS[1]local limit = tonumber(ARGV[1])local current = tonumber(redis.call('get', key) or "0")if current + 1 > limit then return 0else redis.call("INCRBY", key, "1") redis.call("EXPIRE", key, "1") return 1end
  5. Sentinel组件

    功能:提供限流、熔断、流量控制等API,支持可视化管控台。

    适用场景:Spring Cloud微服务架构中的分布式限流。

四、架构设计中的限流策略
  1. 分层限流

    网关层:宽松限流,拦截大部分异常流量(如Nginx限制QPS为1000)。

    服务层:精细限流,结合中间件(如Redis)控制核心接口(如商品详情页QPS≤200)。

    数据层:极端限流,保护数据库(如MySQL连接数≤50)。

  2. 动态调整

    根据系统负载实时调整限流阈值,例如:CPU使用率>80%时自动降低QPS上限。

  3. 降级与熔断

    限流触发时返回降级响应(如缓存数据或默认值),避免系统崩溃。

五、具体实现手段
  • Tomcat限流:通过maxThreads参数限制最大线程数(默认150),超量请求排队。
  • 时间窗口算法:利用Redis有序集合(ZSET)记录请求时间戳,统计窗口内请求数。
  • 漏桶算法:使用Redis-Cell模块(基于Redis的漏桶实现)。
  • 令牌桶算法:通过Guava的RateLimiter类实现单机限流。

总结:限流需结合业务场景选择算法与方案,单机环境可用Guava或Tomcat配置,分布式系统推荐Redis+Lua或Sentinel。分层限流与动态调整可提升系统鲁棒性,避免因流量突增导致雪崩效应。