一、限流基础概念

1.1 什么是限流

限流(Rate Limiting / Traffic Shaping)是一种通过控制单位时间内允许通过的请求数量、并发连接数或数据传输速率,来保护系统不被突发流量冲垮的防护手段。其核心思想是:在系统容量边界内,有选择地拒绝或延迟部分请求,确保核心服务对大多数用户仍然可用。

限流本质:用一部分请求的失败(或被延迟),换取整体系统的稳定与低延迟。

限流通常作用于以下三个维度:

维度 控制对象 典型指标 示例
速率(Rate) 单位时间内的请求次数 QPS、RPS、TPS 每秒最多处理 1000 次 API 调用
并发(Concurrency) 同时处理中的请求数 活跃连接数、goroutine 数 最多同时处理 200 个 WebSocket 连接
容量(Capacity) 累积可突发的工作量 令牌桶容量、队列深度 突发时可积压 500 个任务到缓冲队列
限流核心概念图 限流核心概念图 请求入口 限流判断 速率 / 并发 / 容量 ✅ 通过 ⏳ 排队/降级 ❌ 拒绝 限流结果 通过 → 正常处理 排队 → 缓冲等待 拒绝 → 返回 429/503 限流是系统自我保护的第一道防线,在请求到达业务逻辑之前进行判断

1.2 为什么需要限流

在分布式系统中,限流不是可选项,而是保障服务稳定性的必选项。以下四个场景最能说明限流的必要性:

  1. 防止资源耗尽:数据库连接池、线程池、内存、CPU 等资源都有上限。无限制的请求会迅速耗尽资源,导致服务完全不可用。
  2. 隔离故障扩散:单个服务的过载可能通过 RPC 调用链扩散到上游和下游,形成雪崩效应。限流在源头切断过载传播。
  3. 保障公平使用:在多租户系统中,一个租户的突发流量不应挤占其他租户的服务容量。限流实现租户级别的资源隔离。
  4. 控制成本:云服务按量计费,无限制的流量会导致不可控的账单。限流将资源消耗控制在预算范围内。
压测视角:在性能压测中,限流点往往是系统的瓶颈定位锚点。通过观察限流触发时的 QPS 和延迟分布,可以精确推断系统的真实容量上限。

1.3 限流与熔断降级的关系

限流、熔断、降级是分布式系统稳定性的三大支柱,它们既有明确分工,又需要协同配合。以下表格清晰对比三者的核心差异:

机制 触发条件 动作 恢复方式 典型场景
限流 请求速率/并发超过阈值 拒绝或延迟请求 流量回落到阈值以下后自动恢复 秒杀、热点 Key、突发流量
熔断 错误率/延迟超过阈值(通常基于滑动窗口统计) 快速失败,停止调用下游 经过冷却时间后尝试半开探测 下游服务故障、网络分区
降级 资源紧张或依赖故障 关闭非核心功能,返回降级结果 人工或自动恢复 大促时关闭评论、推荐等非核心服务
限流、熔断、降级协同关系图 限流 · 熔断 · 降级 协同关系 限流 Rate Limiting 熔断 Circuit Breaker 降级 Degradation 协同流程:限流在前 → 熔断在中 → 降级在后 限流失败 → 熔断保护下游 → 降级牺牲非核心功能保核心 限流职责 • 控制入口流量 • 防止资源耗尽 • 基于速率/并发 • 自动恢复 熔断职责 • 监控调用错误率 • 快速失败 • 防止雪崩 • 半开探测恢复 降级职责 • 关闭非核心功能 • 返回兜底数据 • 人工/自动决策 • 保障核心链路
常见误区:很多团队将限流和熔断混为一谈。限流是主动预防,在系统健康时就开始控制;熔断是被动保护,在系统已经出现故障时切断调用链。两者必须同时部署,不能相互替代。

1.4 限流在 Go 服务中的典型位置

在 Go 微服务架构中,限流可以部署在多个层级,每个层级解决不同的问题:

  • 网关层(如 Kong、APISIX、自研网关):全局流量控制,基于 IP、Token、路由进行限流。
  • 中间件层(如 Gin 中间件、gRPC 拦截器):服务级别的限流,针对特定接口或方法。
  • 业务逻辑层:精细化限流,例如针对用户 ID、商品 ID 等业务 Key 进行限流。
  • 资源访问层(数据库、缓存、消息队列):保护底层资源不被过度使用。
Go 限流实战要点:Go 标准库 golang.org/x/time/rate 提供了基于令牌桶的限流实现;对于更复杂的场景(如自适应限流、分布式限流),可以使用 github.com/uber-go/ratelimit 或基于 Redis + Lua 的自定义方案。

1.5 限流与尾延迟的关系

限流对尾延迟(Tail Latency,即 P99/P999 延迟)有直接影响:

限流策略 对尾延迟的影响 说明
无限流 尾延迟急剧升高 请求排队堆积,P99 延迟从 10ms 飙升到 10s+
固定速率限流 尾延迟稳定在可控范围 超出容量的请求被拒绝,剩余请求延迟正常
自适应限流 尾延迟最优 根据实时延迟动态调整限流阈值,在吞吐和延迟之间取得平衡
排队 + 超时 尾延迟受队列深度控制 队列满时拒绝,队列内请求延迟可控