1. 限流基础:为什么需要限流?

1.1 限流的本质与必要性

在微服务架构中,限流(Rate Limiting) 是一种通过控制单位时间内请求量的方式,保护系统不被突发流量冲垮的核心手段。没有限流的系统,就像没有保险丝的电路——一旦电流(流量)超过线路(服务)的承载能力,整条线路就会烧毁。

核心观点:限流不是限制业务增长,而是为系统提供“可控的退化”能力。当流量超过阈值时,系统主动拒绝部分请求,确保核心功能仍能正常响应,避免雪崩式崩溃。

1.2 限流在微服务中的核心作用

限流在微服务体系中承担着多重关键角色,下表总结了其四大核心作用:

核心作用 说明 典型场景
防止资源耗尽 限制 CPU、内存、数据库连接池、线程池等有限资源的过度使用 秒杀活动、热点新闻推送
保障服务质量 避免因高负载导致响应时间(RT)急剧上升,维持尾延迟(Tail Latency)在可接受范围 API 网关、实时推荐服务
公平分配资源 在多租户系统中,确保每个租户或调用方获得公平的配额 开放平台 API、SaaS 服务
成本控制 按流量付费的云服务中,限流可防止意外的高额账单 第三方 API 调用、日志采集

1.3 常见限流场景

限流并非只存在于网关层,它在微服务的各个层级都有应用。以下是三种最常见的场景:

  • 网关层限流(入口限流): 在 API Gateway 或反向代理(如 Nginx、Kong)处对全局流量进行整形,是最外层的防护屏障。通常基于 IP、用户 ID、URL 路径等维度进行限流。
  • 服务层限流(业务限流): 在具体微服务内部,针对特定接口或方法进行限流。例如,订单服务的“创建订单”接口与“查询订单”接口可以设置不同的限流阈值。
  • 资源层限流(基础设施限流): 针对数据库连接池、Redis 连接、消息队列等底层资源进行限流。当资源池耗尽时,直接拒绝上游请求,避免阻塞蔓延。
实战建议:在 Go 微服务中,推荐采用“网关层 + 服务层”双层限流策略。网关层做粗粒度限流(如 QPS 1000),服务层做细粒度限流(如核心接口 QPS 100,非核心接口 QPS 20),形成纵深防御。

1.4 限流与尾延迟的关系

限流与尾延迟(Tail Latency) 之间存在直接关联。当系统负载超过其最佳吞吐点时,请求的响应时间会急剧增加,尤其是 P99(99% 分位)延迟会显著恶化。限流通过主动拒绝超量请求,将系统负载控制在“膝盖点”以下,从而稳定尾延迟。

下图展示了限流如何保护系统,避免进入“过载-延迟飙升-超时重试-更严重过载”的恶性循环:

限流保护系统避免过载恶性循环 限流保护系统:避免过载恶性循环 正常流量区域 请求量 ≤ 系统最佳吞吐点 响应时间稳定(P99 < 100ms) 资源利用率健康(CPU < 70%) 过载区域(无限流) 请求量 > 系统最佳吞吐点 响应时间飙升(P99 > 1000ms) 资源耗尽,请求排队积压 流量突增 恶性循环(无限流时) 过载 → 延迟飙升 → 客户端超时重试 → 更多请求 → 更严重过载 → 系统崩溃 限流干预 限流后效果 拒绝超量请求 → 系统负载回到安全区 → 尾延迟恢复稳定 → 核心功能正常响应

1.5 限流的核心指标与术语

在深入限流算法之前,需要先掌握以下关键指标:

指标 定义 常见单位 说明
QPS 每秒查询数(Queries Per Second) req/s 最常用的限流指标,衡量系统吞吐能力
TPS 每秒事务数(Transactions Per Second) tps 通常用于数据库或包含多个步骤的业务操作
并发数 系统同时处理的请求数量 个 与 QPS 和响应时间相关:QPS = 并发数 / 平均响应时间
令牌桶容量 令牌桶算法中允许的最大突发请求量 个 控制短时间内的流量尖峰
漏桶速率 漏桶算法中恒定的处理速率 req/s 严格平滑流量,不允许突发

1.6 限流与熔断、降级的区别

限流常与熔断(Circuit Breaker)和降级(Degradation)一起讨论,三者共同构成微服务的稳定性三板斧。下表清晰区分了三者的定位:

机制 触发条件 动作 恢复方式 典型工具
限流 请求量超过预设阈值 直接拒绝新请求(返回 429 Too Many Requests) 流量回落到阈值以下后自动恢复 golang.org/x/time/rate、Sentinel
熔断 错误率或延迟超过阈值(如 50% 请求失败) 快速失败,不再调用下游服务 经过冷却时间后,尝试半开探测 hystrix-go、resilience4j
降级 系统资源紧张或依赖服务不可用 返回降级结果(如缓存数据、默认值) 手动或自动恢复 自定义 fallback 逻辑
常见误区:限流不能替代熔断。限流是“事前”预防,熔断是“事中”保护。当限流未能完全阻止过载时,熔断作为第二道防线,防止故障扩散。在实际 Go 微服务项目中,建议同时配置限流和熔断策略。

1.7 本章小结