接口已经用流式生成器返回,前端仍然要等全部结束才一次显示,日志显示服务端是逐段输出的。

一开始怀疑是「压缩中间件把流攒成整包」,查了一圈,方向不对。

原因不止一个,得分开看。中间层开启了响应缓冲。少数情况下是响应头缺少流式声明。

还有一种情况,客户端自身的缓冲没有关闭。

返回流式响应对象并设置头部

return StreamingResponse(gen(), media_type='text/event-stream')

接着关闭代理缓冲

proxy_buffering off;

禁用对流的压缩

python -c "print('skip gzip for stream')"

末了确认服务端逐段刷新

python -c "print('yield chunk + flush')")

中间停过一次,把已经改的东西回滚干净,再重新来一遍。

同样的操作我在测试机上先走了一遍,线上只做验证过的部分。

别只看报错消失,验证要多做一步。前端能逐字显示内容,首字时间降到一秒以内,长回答不再等待。

很多框架默认会缓冲生成器输出,明明写了流式却看不到效果,优先检查中间层而不是改业务代码。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189