nginx 1.24 在 /api/ 上开了 proxy_cache,上游返回 text/event-stream,第二个用户进来收到的第一段是上一个人的回答,流还正常结束。

一开始怀疑是「proxy_buffering 开着,流被攒成整包」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。SSE 响应没有 Cache-Control 的 no-cache。另一种情况是proxy_cache 的 key 没有按请求体区分。

少数情况下是缓存有效期配置覆盖了动态接口。

上来先看响应头有没有禁缓存

curl -sI https://example.com/api/chat | grep -i -E 'cache-control|content-type'

给流式接口关缓存与缓冲

python -c "print('proxy_cache off; proxy_buffering off;')"

上游补上响应头后复测

curl -sN https://example.com/api/chat -H 'Content-Type: application/json' -d '{"q":"hi"}' | head -3

末了换一个会话再取首段对比

curl -sN 'https://example.com/api/chat?sid=2' -d '{"q":"hi"}' | head -1

这次没动代码,只在配置和运行环境上找原因。

隔了一天再看,现象没变,说明不是偶发。

那几天正好在做别的变更,先把时间线对齐才敢动手。

别只看报错消失,验证要多做一步。两个不同会话拿到的首段内容不同,响应头带 no-cache,SSE 仍逐条推送。

默认缓存策略对动态接口是危险的,流式响应必须在网关层显式排除。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189