Skip to content

限流 ​

限流是保护服务不被过载请求打垮的重要手段,通过限制请求速率,确保服务在容量范围内稳定运行。限流可以防止恶意攻击、流量突增、资源耗尽。

为什么需要限流 ​

保护服务:服务容量有限,超过容量的请求会导致服务响应变慢或崩溃。

保护依赖:服务依赖的第三方服务有容量限制(如 API 配额),超过限制会被封禁。

防止雪崩:服务故障时,限流可以减少故障服务的请求,避免雪崩。

公平使用:防止个别用户占用过多资源,保证其他用户的正常使用。

限流算法 ​

固定窗口 ​

固定窗口将时间分成固定大小的窗口,如 1 分钟,每个窗口内限制请求数。请求到达时,检查当前窗口的请求数,如果未超过限制则放行,否则拒绝。

固定窗口的问题:窗口边界问题(窗口边界处可能有双倍请求)、不平滑(窗口前期大量请求,后期无请求)。

滑动窗口 ​

滑动窗口将时间分成更小的单元,如 1 秒,记录每个单元的请求数。请求到达时,统计最近时间窗口(如 1 分钟)的请求数,如果未超过限制则放行,否则拒绝。

滑动窗口的优势:平滑、无边界问题。

滑动窗口的问题:内存占用大(需要记录每个单元的请求数)、实现复杂。

漏桶 ​

漏桶以恒定速率处理请求,请求先进入桶中,桶满后拒绝请求。漏桶的速率固定,输出平滑。

漏桶的优势:平滑输出、可以应对突发流量(桶可以缓存一定请求)。

漏桶的问题:无法应对持续突发流量(桶满后拒绝请求)、桶的大小需要合理设置。

令牌桶 ​

令牌桶以恒定速率放入令牌,请求到达时消耗令牌,有令牌则放行,否则拒绝。令牌桶可以应对突发流量(桶中可以积累令牌)。

令牌桶的优势:可以应对突发流量、限流速率可变(动态调整令牌放入速率)。

令牌桶的问题:实现复杂、需要合理设置桶的大小和令牌放入速率。

分布式限流 ​

单机限流只能限制单个实例的请求,分布式限流需要限制所有实例的总请求。分布式限流可以通过 Redis 实现,使用 INCR 或 Lua 脚本实现原子计数。

分布式限流的问题:Redis 成为瓶颈、Redis 故障影响限流、网络延迟影响限流精度。

限流维度 ​

QPS 限流 ​

每秒请求数限流,限制每秒的请求数。适用于短时间请求。

并发限流 ​

并发请求数限流,限制同时处理的请求数。适用于长连接请求。

用户限流 ​

根据用户 ID 限流,限制每个用户的请求速率。防止个别用户占用过多资源。

IP 限流 ​

根据 IP 限流,限制每个 IP 的请求速率。防止恶意攻击。

接口限流 ​

根据接口限流,不同接口设置不同的限流策略。核心接口限流宽松,非核心接口限流严格。

限流策略 ​

直接拒绝 ​

请求超过限流阈值时直接拒绝,返回错误码或错误信息。简单但影响用户体验。

排队等待 ​

请求超过限流阈值时排队等待,有请求完成则处理排队请求。可以保证所有请求最终被处理,但会增加延迟。

Warm Up ​

限流阈值从较小值逐渐增加到目标值,避免系统启动时大量请求导致故障。适用于缓存预热、系统启动。

匀速排队 ​

请求以匀速通过,平滑处理请求。漏桶和令牌桶都可以实现匀速排队。

主流限流实现 ​

Sentinel ​

Sentinel 是阿里开源的流量防卫组件,提供限流、熔断降级、系统保护。

Sentinel 的限流:QPS 限流(直接拒绝、Warm Up、匀速排队)、并发线程数限流、热点参数限流。

Sentinel 的优势:性能高、实时监控、规则动态配置、生态完善。

Guava RateLimiter ​

Guava RateLimiter 是 Google Guava 的限流库,基于令牌桶算法。

Guava RateLimiter 的特性:平滑限流、支持预热、简单易用。

Guava RateLimiter 的问题:单机限流、不支持分布式。

Redis + Lua ​

使用 Redis 存储计数,Lua 脚本保证原子性,可以实现分布式限流。

Redis + Lua 的优势:分布式、性能高、灵活。

Redis + Lua 的问题:Redis 成为瓶颈、需要处理 Redis 故障。

Nginx 限流 ​

Nginx 提供 limit_req_module(漏桶)和 limit_conn_module(并发限流)。

Nginx 限流的优势:网关层限流、性能高、配置简单。

Nginx 限流的问题:只能限制经过 Nginx 的请求、不支持复杂限流策略。

限流的最佳实践 ​

分层限流:网关层限流(粗粒度)、应用层限流(细粒度),形成多级防护。

限流阈值设置:根据压测结果设置限流阈值,留有余量。根据业务重要性设置不同的限流策略。

限流监控:监控限流触发情况,分析限流原因,调整限流策略。

限流告警:限流触发时及时告警,便于快速响应。

限流降级:限流触发时可以降级处理,返回默认值或错误响应。

限流预热:系统启动时使用 Warm Up 策略,避免启动时大量请求导致故障。

限流是保护服务的重要手段,理解限流算法和权衡,有助于设计合适的限流方案。