什么是服务限流?
- 标签:Spring Cloud、微服务、后端、服务容灾
🏛 业务架构师
服务限流是对进入系统的请求按规则限速,超出部分排队或拒绝,保护系统不过载——过载保护是它区别于熔断(故障隔离)的本质。
为什么业务上必须做:系统容量是有限且可测算的(压测出的水位),而流量是不可控的(营销爆点、爬虫、恶意攻击、上游重试风暴)。超载时系统不是变慢而是崩溃——队列积压、内存耗尽、雪崩。限流就是给系统装"流量保险丝":宁可控地拒绝一部分,不可失控地全部不可用。
常见限流维度(按业务场景选):
- 全局入口限流:网关层按总 QPS 兜底(保命线);
- 接口级限流:核心接口单独配额(下单 5000 QPS),非核心接口低配额——资源按业务价值分配;
- 用户/租户级限流:单用户 10 次/分钟——防刷、防爬虫、防单一大客户吃掉共享容量(SaaS 多租户公平性);
- 热点参数限流:对爆款商品 ID 单独限流(普通商品 100 QPS,爆款 5000)——热点隔离。
限流后的行为设计(业务体验的关键):
- 友好拒绝:返回"太火爆了,稍后再试"(429)+ 前端排队机制(秒杀排队页);
- 分级放行:限流不是一刀切——VIP 用户白名单、核心交易接口优先,限流策略就是业务优先级的代码化。
实现选型:单机用 Guava RateLimiter;分布式用 Sentinel(规则中心化、动态推送、控制台可视)、网关层限流(Gateway + Redis 令牌桶)。
一句话:容量是技术问题,"超了以后谁被拒"是业务问题——限流方案评审必须业务方在场。
🏗 系统架构师
定义:限制单位时间进入系统的请求数或并发数,把流量钉在容量安全线以内——保护自己,也保护共享下游(DB、第三方配额)。
四个算法:
- 固定窗口计数:简单,但窗口边界有 2 倍突刺;
- 滑动窗口:细分小格平滑统计(Sentinel 实现);
- 漏桶:恒定速率流出,绝对平滑但无法应对合理突发;
- 令牌桶:恒速补充令牌加桶容量允许突发——主流默认(Guava、网关 Redis 加 Lua)。
架构设计(比算法重要):
- 层级限流:网关全局(总量)→ 服务级(QPS)→ 接口级(热点参数,按 userId)→ 下游配额保护(DB 连接、第三方 API 配额),各层各管各的预算;
- 阈值从压测来:容量乘安全系数(0.7),配合自适应限流(Sentinel 系统自适应,按负载与 RT 动态)应对容量未知;
- 被限流的行为要设计:返回 429 加 Retry-After、排队等待、降级兜底——裸拒绝等于把压力反弹成用户重试风暴;
- 区分流量类型:核心交易与爬虫、重试流量分级配额,别让重试流量挤占正常额度。
💻 全栈开发专家
对进入系统的流量按阈值削减,只接收"扛得住"的量,超出部分排队/拒绝/降级——容量保护的最后一道闸。
与熔断的区别:限流防"自己被压垮"(入口防御,面向流量),熔断防"被下游拖垮"(出口防御,面向依赖)。
四个维度:
- 限什么:QPS、并发线程数、热点参数(按 userId 限,防单用户刷爆)
- 什么算法:固定窗口(有临界突刺)、滑动窗口(Sentinel 默认)、漏桶(恒速)、令牌桶(允许突发,网关常用)
- 在哪限:
- 网关层:Spring Cloud Gateway
RequestRateLimiter+ Redis(全站/接口级) - 应用层:Sentinel
@SentinelResource(细粒度、支持热点参数) - MQ 层:消费并发控制;DB 层:连接池上限
- 网关层:Spring Cloud Gateway
- 被限的流量怎么办:友好提示(429)、匀速排队、降级数据
java
@SentinelResource(value = "createOrder", blockHandler = "createOrderBlocked")
public Result<Order> create(OrderReq req) { ... }
public Result<Order> createOrderBlocked(OrderReq req, BlockException e) {
return Result.fail(429, "当前下单人数过多,请稍后再试");
}容量从哪来:压测基线 × 安全系数(压测 8000 QPS、线上限 6000),大促前按预期流量重新压测定阈值。