跳转至

百炼网关:用RocketMQ LiteTopic重构大模型限流架构

Ch01.622 百炼网关:用RocketMQ LiteTopic重构大模型限流架构

📊 Level ⭐⭐ | 10.0KB | entities/bailian-gateway-rocketmq-litetopic-llm-rate-limiting.md

百炼网关:用RocketMQ LiteTopic重构大模型限流架构

阿里云百炼网关团队使用 RocketMQ 5.x 的 LiteTopic 轻量级队列形态重构了大模型限流架构,将限流比(性能开销)降低 10 倍,限流导致的用户可感知异常大幅收敛。这套方案将漏桶(Leaky Bucket)从进程内搬到进程外,构建出百万级物理隔离队列 + 动态速率调度 + 零运维弹性的「分布式漏桶矩阵」。

核心内容

大模型限流的挑战

百炼作为阿里云大模型服务平台,承载百万级用户同时调用千问等数十种大模型。当平台用户从千级增长到百万级,限流系统面临的不再是「防刷」这类传统问题,而是「如何在有限 GPU 池中实现百万租户各自独立、按需弹性的精细化流量治理」。GPU 扩容周期长、单价高,供给受制于硬件交付节奏,「GPU 池子有多大」几乎直接决定「今天能服务多少客户」。

传统的「一个限流器卡在网关上」的范式面临三重叠加的限流需求:

  1. 基于 SLA 承诺的基础限流:稳定、可计量、可观测
  2. 用户之间及多账号细粒度管控:在 User + Model 维度做交叉约束
  3. 超大客户的扩容与突发承接:额度调大后突发真正来时,硬限返回 503 影响体验,放过去又让 GPU 过载殃及其他租户

算法选择:固定窗口 + 漏桶

  • 固定窗口(而非滑动窗口):对短期波动更宽容,边界处的突发不会被精确计算
  • 漏桶(而非令牌桶):漏桶匀速放行更契合 GPU 这种稳态友好、尖峰敏感的下游,令牌桶天然允许突发恰恰是 GPU 最怕的形态

传统 Topic/Group 方案的瓶颈

最初落地用 RocketMQ 传统 Topic,为每个 User + Model 单独建 Topic 与 Consumer Group,但三个痛点很快暴露:

  • 元数据重、生效慢:传统 Topic/Group 需要预先创建,生效时间几十秒,新用户突发流量到来时出现短时间异常
  • 机器利用率低:必须给每个客户单独切机器,哪怕客户今天一条消息都没有机器也要常驻,成本随客户数乘法膨胀
  • 单 Topic 暴涨的株连效应:多客户数据塞进同一 Topic,某个用户消息激增时会阻塞其他用户,最终退回「一客户一组机器」

LiteTopic 三件套

RocketMQ 5.x 的 LiteTopic 三个关键特性正好对应上述三个痛点:

  1. 轻量元数据:单 Broker 支撑百万级 LiteTopic,客户端往不存在的 LiteTopic 发消息即可自动建出,无活动一段时间后由 Broker 自动清理
  2. 差异化订阅:同一 Consumer Group 下不同消费实例可订阅不同的 LiteTopic 子集,不会引发堆积或丢失
  3. Suspend 消费控制:消费回调中返回 Suspend N 毫秒即可让 Broker 暂停对该 LiteTopic 的拉取,不影响其他 LiteTopic 的拉取节奏——这是漏桶在 Broker 层落地的关键开关

重构后的架构

  • 发送侧:通过基础限流校验后,按 User + Model 写入对应 LiteTopic,名称天然编码用户与模型信息
  • 消费侧:原来按客户切分的几十组机器合并为一组统一 Pod,通配符订阅全部 LiteTopic,新增客户无需改代码、无需重启
  • 限流逻辑:收敛到消费线程内几行判断——命中则 Suspend N,否则转发模型并 ACK

每个 User + Model 拥有一个独立漏桶,整个矩阵共享同一组消费机器,资源池随总流量伸缩而非按客户数线性增长。

关键技术细节

海量 LiteTopic 下的消费性能:LiteTopic 在 Broker 侧引入就绪集合(Ready Set)事件驱动机制(类似 epoll),只有真正有新消息写入的 LiteTopic 才进入就绪集合。Pull 开销只与「当前时刻就绪的 LiteTopic 数量」成正比,而非「总订阅数」。POC 压测中,单 Broker 承载 200 万队列(200 客户端 × 1 万 LiteTopic),平均消费延迟稳定在 12ms。

Suspend vs Sleep 的本质区别

  • Thread.sleep(300):线程级阻塞,通过共享线程池扩散到无关租户——被限流的 LiteTopic 占住线程不释放,当被限流数增加时正常 LiteTopic 拿不到线程而全部堆积
  • Suspend 300:Broker 级拉取流控,消费线程返回后立即释放回线程池,与其他漏桶在线程层面完全解耦——仅被限流的 LiteTopic 堆积,其余正常

核心区别在于谁为等待买单。

深度分析

1. 限流从「防御题」变成「资源调度题」

大模型时代的限流本质上由 GPU 的物理稀缺性定义。传统限流面对的是 CPU 和带宽这类可以秒级弹起的资源,而 GPU 扩容以周甚至月为单位。这改变了限流的底层逻辑:不是「防刷」,而是「在有限池中做资源调度最优分配」。百炼网关的重构体现了这种认知转变。

2. 物理载体的选择决定了系统上限

当限流额度大到突发流量可能压垮网关进程,漏桶必须从进程内搬到进程外。MQ 是天然候选,但关键追问在于:能否支持百万级队列?能否按需创建?流控粒度是否足够精细?LiteTopic 的三个特性——轻量元数据、差异化订阅、Suspend 控制——恰好形成了一套完整的「隔离+调度+弹性」三位一体方案。这种将「业务逻辑依赖基础设施层特性」的设计范式,是构建云端高性能系统的关键方向。

3. 租户隔离的成本从乘法变加法

传统方案下,隔离强度每提升一级,机器成本就乘一个系数。LiteTopic 的方案是:每个 User + Model 拥有物理隔离的队列,所有队列共享同一组消费 Pod,资源池随总流量伸缩而非随客户数膨胀。隔离强度不降,成本从乘法变回加法——这对公有云服务有直接的商业价值,也为其他多租户系统提供了一个可复用的参考。

4. Suspend vs Sleep 的线程经济学

Suspend 将「等待的成本」从客户端转移到了 Broker,消费者线程不阻塞、不等待、不浪费。这在多租户共享消费组、大量用户同时被限流的场景下,是决定系统公平性的关键——无论多少 User+Model 正在被限流,剩余用户始终有空闲线程可用。这种「谁为等待买单」的设计哲学,可以推广到任何共享资源池下的限流架构。

5. 与 LLM 推理特性的深度契合

漏桶模型特别适合 GPU 推理服务的原因是:推理请求的「稳态友好、尖峰敏感」特性——GPU 批处理在连续到达中效率最高,突发尖峰带来的排队延迟和内存碎片会显著降低吞吐。LiteTopic 的分布式漏桶矩阵本质上是将请求流「整流」为GPU友好的连续流。这种对下游特性的深度理解,是选择技术方案的前提。

实践启示

  1. 大模型服务的限流架构应围绕 GPU 稀缺性设计:GPU 无法秒级弹性扩容,因此限流不仅是拒绝超额请求,更是「如何在有限池中做资源调度」。评估自己的模型服务时,先回答「GPU 扩容周期是多少」。
  2. 优先选择基础设施层提供租户隔离的方案:将隔离从「靠业务代码维护」下沉为「靠基础设施天然提供」,可以同时提升隔离强度和降低运维成本。LiteTopic 的「命名规则即隔离」是一个可复用的设计模式。
  3. Suspend 优于 Sleep 的通用原则:在共享线程池的多租户系统中,将等待成本从客户端线程转移到队列基础设施是更公平的选择。任何时候当你在消费循环中考虑 Thread.sleep,评估能否改为返回 Suspend 让队列系统处理等待。
  4. 关注「就绪集合」模式解决大规模拉取性能:当系统需要从大规模队列集合中消费时,类似 epoll 的事件驱动机制(而非逐个轮询)是避免性能随订阅数线性恶化的关键。
  5. 选择漏桶而非令牌桶用于 GPU 限流:漏桶的匀速放行与 GPU 批处理的特性天然匹配。如果下游是稳态友好的计算资源(GPU、TPU),漏桶是正确的选择;如果下游支持突发消费,令牌桶可能更合适。

相关实体

原文存档