Fluxio
← 返回博客

实时聊天50路并发压测:SSE流式接口的并发上限实测

SSE 与接口ZH

§1 测试设计:50 路 SSE 并发流的压测台怎么搭

这场测试模拟的是实时聊天产品在高峰期的真实形态:几十位用户同时在线,每个人都盯着屏幕等 token 一个个蹦出来。我们用一个 Node.js 脚本同时发起 50 路 SSE 连接,模型统一选用响应偏快的 Claude Haiku 4.5,提示词固定为要求输出约 400 个 token 的长答任务,保证每一路都能跑到完整的 token 流,而不是被短回复掩盖真正的瓶颈。脚本逐路记录首字节时间、完整流时长、断流次数、重试次数、收到的 token 速率与最终状态码,并把每一路的时间线打点写入日志,方便事后回放哪一秒发生了拥堵。

压测环境与产品端保持一致:客户端走 OpenAI 风格的流式接口,把 stream 参数打开,逐块读取 SSE 事件;服务端入口统一使用 https://api.fluxioapi.com,OpenAI 风格客户端在后面补上 /v1 就能直接复用现有 SDK。这意味着并发实验不需要改写请求层代码,测出来的数字可以直接对应到生产环境。为了排除单轮偶然性,每组参数重复三轮取中位数,并在轮次之间留出足够的冷却时间,避免上一轮的限流影响下一轮的读数。

  • – 用 50 路并发 SSE 连接模拟高峰时段的实时聊天流量
  • – 固定输出长度以便横向比较首字节时间与流总时长
  • – 逐路记录断流、重试、限流响应码与吞吐曲线
  • – 分别在单 key 与多 key 场景下重复三轮取中位数

§2 并发数爬升时首字节时间的真实变化曲线

并发从 5 路升到 20 路时,首字节时间几乎没有变化,中位数稳定在几百毫秒量级,token 流的推进节奏也保持均匀,用户体感就是打字机式的稳定输出。跨过 20 路之后,曲线开始抬头,到 35 路时首字节时间比基线高出约四成,并且出现了零星的流中断,表现为输出到一半突然停住。到 50 路时,约十分之一的连接收到限流响应,另一部分连接虽然握手成功,但前几个 token 的等待明显变长,最慢的一路比最快的慢了近一倍。

更值得注意的是尾部延迟的形状。低并发时,首字节时间分布很窄,几乎所有连接都在同一区间完成握手;高并发时分布被拉出长尾,正是这条长尾决定了用户感知到的体验差。很多团队只盯平均值,结果在压测报告里看不到问题,上线后却被投诉卡顿。我们的判定是:单 key 的舒适并发区间大约在 20 到 30 路,超过这个区间就应该做请求排队。如果把 50 路请求分散到多个 key 上,整体表现会平滑很多,但产品端必须自己做 key 轮换、健康检查与失败兜底,复杂度会整体转移到你的代码里。

§3 限流信号识别:哪些响应代表真的撞到并发墙

并发撞墙并不总是以明确的 429 出现,这是实测里最容易踩的坑。有的连接表现为握手成功但长时间不吐 token,有的是在流进行到一半时突然关闭,前端看到的是光标停住,接口日志里却没有报错。把这些情况统一归因成网络问题会导致重试风暴,反而把服务打得更糟。真正的判别依据是状态码、响应头里的重试提示、同一时刻失败连接的聚集程度,以及失败是否集中在并发爬升的那一秒。

在流式场景里还要额外区分两类失败:一类是建连阶段的拒绝,这类信号清晰,客户端可以直接进入退避流程;另一类是流中途的截断,此时可能已经消耗了一部分 token,整体重发既浪费成本又让用户重复看到前半段输出。正确做法是把输出视为可续接的过程,记录已经收到的片段,只补发剩余部分。实测里换用 Gemini 3.1 Pro 这类输出更长的模型,流中断造成的浪费会更加明显,续接逻辑的价值也随之放大。

  • – 收到 429 或带重试时间提示的响应时按服务端建议延后重试
  • – 握手成功但超过阈值未收到首字节时主动断开并重新排队
  • – 流中途断开时优先续接而非整体重发,避免重复生成长输出
  • – 短时间内大量连接同时失败时立即降级并发而不是逐个重试

§4 三种退避策略实测:立即重试最伤吞吐

我们对撞到并发墙之后的处理方式做了三组对照。第一组是失败立即重试,结果是大量连接在同一毫秒再次涌入,限流窗口被不断刷新,50 路里最终成功的只有三十几路,整体完成时间反而最长,而且日志里能看到明显的重试放大效应。第二组是固定间隔退避,表现稳定但尾部延迟偏高,长输出任务排在后面的用户等待明显,容易被误判成模型变慢。第三组是带随机抖动的指数退避加客户端侧排队,也就是把超出舒适区的请求放进一个本地队列按顺序放出,成功率接近满值,整体完成时间最短,首字节时间的长尾也被压平。

排队的关键在于把并发控制做成一个信号量:先估算舒适并发数,再让超出的请求在队列里等待令牌释放。抖动的作用是防止多台应用实例在同一时刻集体重连,这是分布式部署下最容易被忽略的同步风暴。实测中换成 Gemini 3.1 Pro 这类输出更长的模型,策略优劣排序没有变化,只是排队带来的收益更大,因为单路占用时间越长,并发槽位就越紧张。结论明确:客户端排队加指数退避是唯一值得放进生产代码的方案。

§5 并发上限的配额规划与流式产品落地建议

做实时聊天、协同编辑或语音字幕这类产品时,不要按平均在线人数规划并发,要按峰值同时开口的人数规划,并预留至少三成余量。一个用户在输入框打字时并不占用流式槽位,但一旦按下发送就会立刻占用,突发往往集中在同一秒。前端应当展示流式状态而不是空白等待,比如逐 token 落字的动画和排队提示,让用户知道连接在推进。后端要把并发数做成可调参数,因为模型、输出长度和时段都会改变舒适区间,把它写死在配置里等于埋雷。

另一个容易忽略的维度是成本与并发的耦合。流式接口按 token 计费时,重试风暴会让同一段内容重复计费,排队策略在省钱上的价值往往大于它在体验上的价值。如果不想自己维护多 key 轮换、重试兜底和流式兼容层,可以考虑 Fluxio:它是一个流式优先、按 token 计费的 AI 接口中转,一个 key 就能调到 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen、Grok 等模型,回复逐 token 到达,并且兼容 Claude Code、Codex、Gemini CLI 和任意 OpenAI SDK。实测里用它做单入口的并发实验,省掉了大量接线工作,让我们能把精力集中在压测本身。最终判定:把并发控制放在客户端队列,把模型多样性交给统一入口,是目前最省心的组合。邀请好友注册还能拿到对方付费金额 17% 的返佣。

现在就注册 Fluxio,开启你的实时流式测试。

创建 Fluxio 账号 →

顺流再读几篇