504超时主因是nginx的proxy_read_timeout过短或python未正确响应keepalive,需按接口最长耗时+20%设timeout,并配合同步后端超时控制及依赖客户端超时。

504 超时不是 Python 代码本身“慢”导致的,而是 Nginx 在等待 Python 进程返回响应时主动放弃了连接——它等不及了。
proxy_read_timeout 设置过短是最常见原因
绝大多数偶发 504 都卡在 proxy_read_timeout 这一关。Nginx 默认值是 60 秒,但你的 Python 接口(比如报表导出、AI 推理、批量同步)实测耗时可能在 3–8 分钟。只要某次请求刚好超过 60 秒,Nginx 就会断开并返回 504,而此时 Python 进程可能还在正常跑着。
- 不要盲目设成 3600 秒:超长 timeout 会导致死连接堆积、worker 连接数耗尽
- 应根据接口最长稳定耗时 + 20% 安全余量来设:比如导出接口压测最久 480 秒,就设
proxy_read_timeout 600; - 必须配合后端实际超时控制:Flask 用
timeout参数、FastAPI/Uvicorn 用--timeout-keep-alive或--limit-concurrency,避免 Nginx 等着一个永远不结束的协程
Python 进程未正确响应 keepalive 导致连接僵死
Nginx 启用了 keepalive 复用连接,但 Python 应用(尤其是用 Gunicorn/Uvicorn 时)若未配置或配置不当,会在处理完请求后不发 FIN 包、也不关闭 socket,Nginx 就一直以为连接还“活着”,直到 proxy_read_timeout 到期才强行 kill,造成偶发性 504。
- Gunicorn 需显式加
--keep-alive 5(单位秒,建议 ≤ Nginx 的keepalive_timeout) - Uvicorn 推荐加
--timeout-keep-alive 5,同时确保--http-timeout 600≥ Nginx 的proxy_read_timeout - 检查 Nginx 是否开了
proxy_http_version 1.1;和proxy_set_header Connection '';,否则 keepalive 不生效
上游依赖拖慢响应,但没暴露在日志里
504 表面是“Nginx 等不到 Python”,但根因常藏在 Python 内部:一次数据库慢查询、调第三方 API 卡住、Redis 连接池耗尽、甚至本地磁盘 IO 延迟,都可能让整个请求 hang 住。这些不会报错,也不会打异常日志,只表现为“无响应”,最终被 Nginx 判为超时。
- 在 Python 接口入口加简单计时:用
time.time()打点,记录 DB 查询、HTTP 调用、文件读写各阶段耗时 - 用
ps aux --sort=-%cpu或top -H -p $(pgrep -f "uvicorn|gunicorn")查看 Python worker 线程是否卡在某个系统调用上(如futex、epoll_wait) - 对关键外部依赖(DB、Redis、HTTP)务必设置客户端级 timeout:比如
requests.get(url, timeout=(3, 10)),别让它无限等
真正难排查的不是“超时多久”,而是“为什么这次超了、下次又没超”。重点盯住连接复用状态、下游依赖的稳定性、以及 Python 进程是否真在工作——而不是只调大 Nginx timeout。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











