后端已分段发送 SSE,但前端一次性收到全部内容,如何排查?

考查重点:应用、代理与客户端流缓冲。沿应用写入、代理转发、客户端读取逐段记录到达时间,重点看 flush 与代理缓冲,再区分数据迟到还是 UI 延迟更新

本题目录

参考答案

核心回答

先区分“数据到客户端晚了”与“客户端早已收到、界面却晚更新”。沿服务端生成、应用写出、代理转发、浏览器读取和界面渲染记录同一事件的序号与时间,逐层缩小范围。服务端日志显示多次写入,只能证明程序执行了写操作,不能证明字节已经送到浏览器。

最常见的问题包括应用或压缩缓冲、反向代理响应缓冲,以及前端使用 response.text() 等待整个响应完成。也要检查每条 SSE 事件是否以空行结束,否则解析器会一直等事件边界。

按路径排查

  1. 直连应用:使用 curl -N 观察带序号和时间戳的独立事件。若直连也成批到达,检查生成器是否真的逐步产出、框架是否支持流式写出、阻塞任务是否占住事件循环,以及压缩或中间件是否攒批。
  2. 经过代理再比较:若直连正常、域名访问成批到达,逐个排查 NGINX、网关、负载均衡和 CDN。NGINX 的 proxy_buffering off 控制上游响应缓冲;proxy_request_buffering 控制请求体,不能代替它。
  3. 观察浏览器读取:用 response.body.getReader() 或合格的事件流客户端逐批读取;若调用 response.json()、response.text() 或等全部字符串后再解析,界面只能在结束后看到结果。
  4. 最后检查渲染:记录每次读取与状态更新的时间。一次同步任务堵住主线程、频繁更新造成批处理,或只在终态提交状态,都可能造成“假流式”。

配置与验证的边界

响应头 X-Accel-Buffering: no 可以请求 NGINX 关闭该响应的缓冲,但代理配置可能忽略它;不能认为加一个头就控制了所有中间层。压缩策略、空闲超时和心跳也要分别检查。HTTP/2 不是天然不支持流式,不应把降级为 HTTP/1.1 当成通用解法。

可以构造每隔一小段时间输出一个完整事件的诊断端点,分别测试直连和完整代理链。这个端点用于定位传输问题,不代表真实业务已经通过性能验收。

对应教程

参考资料

相关面经

1 篇

靖安科技

后端工程师(RAG/Agent 项目)
秋招一面
查看原面经 →
追问
后端 SSE 分段推、前端一次性全出来,什么原因

相关题目

4 题