1. 限流基础:什么是限流、为什么需要限流、限流在微服务中的位置
1.1 什么是限流
限流(Rate Limiting / Throttling)是一种通过控制单位时间内允许通过的请求数量、并发连接数或数据传输量,来保护系统不被突发流量冲垮的防御手段。其核心思想是:主动拒绝超出阈值的请求,以保障系统在安全水位下稳定运行。
限流不是“不让用户访问”,而是“在系统容量范围内,公平地分配服务资源”。它通常作用于网关、中间件或业务层,在流量进入核心服务之前进行拦截与整形。
限流三要素:
- 阈值:允许通过的最大请求数/并发数/速率(如 1000 req/s)
- 时间窗口:计数周期(如 1 秒、1 分钟)
- 拒绝策略:超出阈值后的处理方式(直接拒绝、排队等待、降级返回)
1.2 为什么需要限流
在分布式系统中,流量是不可预测的。即使经过容量规划,仍然可能面临以下场景:
| 场景 | 风险 | 限流的作用 |
|---|---|---|
| 突发流量(秒杀、热点事件) | 瞬间 QPS 超过系统上限,导致服务雪崩 | 削峰填谷,保护后端资源 |
| 恶意攻击(DDoS、爬虫) | 大量无效请求耗尽连接池、CPU、内存 | 快速拒绝非法流量,隔离攻击 |
| 上游服务降级或重试风暴 | 失败重试叠加,形成指数级流量放大 | 限制重试速率,防止级联故障 |
| 资源竞争(数据库连接、线程池) | 请求堆积导致响应时间急剧上升 | 控制并发数,维持尾延迟稳定 |
| 多租户隔离 | 某个大客户抢占全部资源 | 按配额限流,保障公平性 |
核心认知:限流不是为了“不丢请求”,而是为了“在有限资源下,让系统不崩溃”。一个被限流拒绝的请求,好过一个让整个服务超时熔断的请求。
1.3 限流在微服务中的位置
在微服务架构中,限流不是孤立的组件,而是贯穿整个请求链路的防御层。下图展示了限流在典型微服务拓扑中的部署位置:
1.4 限流的层次与粒度
限流在微服务中并非单一维度的操作,而是按层次和粒度进行分级部署:
| 层次 | 典型位置 | 限流粒度 | 常用算法 |
|---|---|---|---|
| 接入层 | 负载均衡、API 网关 | 全局 IP / 用户 / API | 令牌桶、滑动窗口 |
| 服务层 | 业务服务、RPC 框架 | 接口 / 方法 / 调用方 | 漏桶、自适应限流 |
| 资源层 | 数据库连接池、线程池 | 连接数 / 并发数 / 吞吐量 | 信号量、最大并发数 |
| 基础设施层 | 消息队列、缓存 | 消费速率 / 带宽 | 速率限制、背压 |
常见误区:很多团队只在网关层做限流,认为这样就够了。实际上,网关限流只能挡住外部流量,无法应对服务间调用产生的内部流量放大(如重试、级联调用)。限流必须分层部署,形成纵深防御体系。
1.5 限流与微服务其他治理手段的关系
限流不是孤立存在的,它与微服务治理中的其他手段协同工作:
协同原则:
- 限流 + 熔断:限流主动拒绝,熔断被动断开,两者互补
- 限流 + 降级:被限流的请求触发降级逻辑(如返回缓存数据、默认值)
- 限流 + 重试:重试必须受限于限流策略,否则会形成重试风暴
- 限流 + 超时:超时后的请求应计入限流计数,避免无效请求占用配额
1.6 限流的核心指标
在设计和评估限流策略时,需要关注以下关键指标:
| 指标 | 定义 | 典型值 | 影响 |
|---|---|---|---|
| QPS | 每秒请求数 | 1000 / 5000 / 10000 | 直接影响系统吞吐量 |
| 并发数 | 同时处理的请求数 | 200 / 500 / 1000 | 影响资源占用和尾延迟 |
| 拒绝率 | 被限流请求占总请求的比例 | < 5% 正常 / > 20% 告警 | 反映系统容量是否充足 |
| P99 延迟 | 99% 请求的响应时间 | < 200ms | 限流不当会导致延迟抖动 |
| 限流精度 | 实际通过量与设定阈值的偏差 | < 5% | 影响流量控制的准确性 |
Go 工程实践要点:
- Go 标准库
golang.org/x/time/rate提供了基于令牌桶的限流实现,适合网关层和服务层 - 对于高精度场景(如金融交易),推荐使用滑动窗口算法替代固定窗口,避免边界突发
- 在 Go 中实现限流时,注意使用
atomic或sync.Mutex保证计数器并发安全 - 限流中间件应放在 HTTP 中间件链的最外层,优先于日志、鉴权等操作
1.7 本章小结
限流是分布式系统稳定性的第一道防线。它通过主动拒绝超出容量的请求,保护后端资源不被突发流量冲垮。在微服务架构中,限流需要分层部署——网关层做全局整形,业务层做精细化控制,基础设施层保护资源。限流不是孤立手段,它与熔断、降级、重试、超时控制共同构成微服务的韧性工程。