FastAPI 跑在 uvicorn 0.30,前面挂 Nginx,前端 EventSource 每 5 秒重连一次,浏览器控制台显示连接被关闭,服务端日志没有异常,本地直连 8000 端口却不会断。
一开始怀疑是「Nginx 的 proxy_read_timeout 与上游不匹配」,查了一圈,方向不对。
原因不止一个,得分开看。uvicorn 默认 keep-alive 5 秒 空闲就关连接。另一种情况是SSE 心跳间隔大于 keep-alive 时间。
另外,响应头缺 Cache-Control 被中间层缓存。
第一件事是把 keep-alive 调到 75 秒再观察
uvicorn app:app --host 0.0.0.0 --port 8000 --timeout-keep-alive 75
给流加 15 秒一次的心跳注释行
grep -n 'yield' app/sse.py
再往下确认 Nginx 的读超时大于心跳间隔
grep -n proxy_read_timeout /etc/nginx/conf.d/llm.conf
响应头显式关掉缓存
curl -N -D - http://127.0.0.1:8000/stream
同一份数据我导出了两份,一份留底,一份拿来试。
这类问题以前遇到过,但这次的触发条件和上次不一样。
恢复的判定其实很直接。EventSource 连续 10 分钟不再重连,Nginx 日志里没有 499,心跳行按 15 秒稳定出现。
提醒一点。心跳必须走同一条流,另开接口探活没有意义,中间层看的是这条连接上有没有字节流动。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
