Docker遇到502 Bad Gateway问题的排查与解决方法
作者:drebander
最近在部署一个内容服务时,遇到线上 502 Bad Gateway。这次故障非常典型:表面现象全部指向 Nginx 和 Docker 网络,最终根因却在应用代码里的一把锁。完整复盘如下。
一、项目背景
本次部署结构很常见:
- 业务服务容器:
story-service(FastAPI + Uvicorn) - 网关容器:
nginx-gateway(反向代理) - 两者都在同一台服务器的 Docker 环境中
- 设计上通过同一个 Docker 网络互通,Nginx 用容器名反代业务服务
部署完成后,用户访问接口返回 502,开始排查。
二、故障现象
1)宿主机探活失败
curl -i http://127.0.0.1:8070/health
返回:
curl: (56) Recv failure: Connection reset by peer
2)容器内探活也失败
容器是精简镜像,没有 curl/ss,改用 Python 探活:
docker exec -i story-service python - <<'PY'
import urllib.request
for p in (8080, 8070):
url=f"http://127.0.0.1:{p}/health"
try:
with urllib.request.urlopen(url, timeout=3) as r:
print(url, "OK", r.status, r.read().decode("utf-8", "ignore"))
except Exception as e:
print(url, "FAIL", repr(e))
PY
结果:
http://127.0.0.1:8080/health->Connection refusedhttp://127.0.0.1:8070/health->Connection refused
这一步非常关键:容器内回环都连不上,说明不是 Nginx 转发层的问题,应用根本没监听端口。
三、排查命令与结论
1)查看容器状态
docker ps -a --filter "name=story-service"
用于判断容器是否在异常重启或退出。
2)查看实时日志
docker logs -f story-service
日志显示数据库初始化成功,但启动流程停在“确保管理员账号”阶段,没有出现 Uvicorn running on ... 监听日志。
3)核对端口映射
docker port story-service
确认了映射关系,但由于容器内端口本身未监听,映射正确也无效。
4)核对启动参数
docker inspect story-service --format '{{.Path}} {{range .Args}}{{.}} {{end}}'
用于确认 uvicorn 启动参数和监听端口是否一致。
5)核对网络连通基础
docker network inspect mynet
确认 Nginx 与业务容器都在同一网络中,排除基础网络隔离问题。
四、根因定位
根因在数据库初始化链路的锁重入:
- 应用启动时执行
ensure_admin_user() ensure_admin_user()内部可能调用create_user()create_user()又会走到get_conn()- 多个函数尝试获取同一把锁
- 代码使用的是
threading.Lock()(不可重入)
结果是同线程重复加锁,启动阶段发生死锁。进程没有直接崩溃,但 startup 卡住,服务端口始终不监听,最终表现为 502。
五、修复方式
将数据库模块锁改为可重入锁:
threading.Lock()改为threading.RLock()
修复后重新部署,日志出现正常监听信息,容器内 health 可达,Nginx 502 消失,服务恢复。
六、两个排障细节
1)docker exec+ heredoc 不要用-t
错误写法会报:
the input device is not a TTY
正确写法是 -i:
docker exec -i story-service python - <<'PY' ... PY
2)python:slim没有curl/ss是常态
不必先改镜像,直接用 Python 内置库做 HTTP 探活即可完成核心定位。
七、复盘总结
这次故障最容易误判为“网络问题”,但真正根因是“应用启动死锁”。
有效的排障顺序是:
- 先看应用是否真正监听端口(容器内回环探活)
- 再看端口映射
- 最后看 Nginx 与 Docker 网络
当 502 出现时,先证明“后端服务真的活着”,再谈代理层配置,效率最高。
到此这篇关于Docker遇到502问题的排查与解决方法的文章就介绍到这了,更多相关Docker遇到502问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
