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 仍逐条推送。
默认缓存策略对动态接口是危险的,流式响应必须在网关层显式排除。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
