这个坑值得记一笔。在 APISIX 3.8 上给模型服务配了路由,流式接口从前端看是一次性吐出来的,首字延迟 5 秒,直连后端只要 0.6 秒,Nginx 层已经关过 buffering。
刚开始盯着「上游返回的 Content-Type 被改写」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。APISIX 默认对上游响应做缓冲;插件链里的 proxy-buffering 没显式关闭;HTTP/2 与压缩中间件把流攒成整包。
第一件事是确认响应头里有没有缓冲相关标记
curl -sI https://api.example.com/v1/chat/completions -H 'Accept: text/event-stream'
接着在路由上关闭上游缓冲
curl -s http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $ADMIN_KEY" -X PATCH -d '{"plugins":{"proxy-rewrite":{}},"upstream":{"pass_host":"node"}}'
然后用 curl 直连 APISIX 观察首包时间
curl -N -s -o /dev/null -w 'ttfb=%{time_starttransfer}\n' https://api.example.com/v1/chat/completions -d @payload.json
剩下的就是对比直连后端与经网关的差异
curl -N -s -o /dev/null -w 'ttfb=%{time_starttransfer}\n' http://127.0.0.1:8000/v1/chat/completions -d @payload.json
隔了一天再看,现象没变,说明不是偶发。
怎么算真的好了,看的是同一批现象。经网关的首包时间降到 0.7 秒内,前端能逐字显示,与直连后端的差异小于 100 毫秒。
流式链路上每一层都可能缓冲,排查时逐跳量首包时间,比一次改一堆配置有效。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
