docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker遇到502 Bad Gateway问题

Docker遇到502 Bad Gateway问题的排查与解决方法

作者:drebander

本文详细描述了线上部署内容服务时遇到的502 Bad Gateway问题,表面现象指向Nginx和Docker网络,但最终发现根因在于应用代码中使用不可重入锁导致的死锁,通过调整锁的类型并进行部署,问题得以解决,需要的朋友可以参考下

最近在部署一个内容服务时,遇到线上 502 Bad Gateway。这次故障非常典型:表面现象全部指向 Nginx 和 Docker 网络,最终根因却在应用代码里的一把锁。完整复盘如下。

一、项目背景

本次部署结构很常见:

部署完成后,用户访问接口返回 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

结果:

这一步非常关键:容器内回环都连不上,说明不是 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 与业务容器都在同一网络中,排除基础网络隔离问题。

四、根因定位

根因在数据库初始化链路的锁重入:

结果是同线程重复加锁,启动阶段发生死锁。进程没有直接崩溃,但 startup 卡住,服务端口始终不监听,最终表现为 502。

五、修复方式

将数据库模块锁改为可重入锁:

修复后重新部署,日志出现正常监听信息,容器内 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 探活即可完成核心定位。

七、复盘总结

这次故障最容易误判为“网络问题”,但真正根因是“应用启动死锁”。
有效的排障顺序是:

  1. 先看应用是否真正监听端口(容器内回环探活)
  2. 再看端口映射
  3. 最后看 Nginx 与 Docker 网络

502 出现时,先证明“后端服务真的活着”,再谈代理层配置,效率最高。

到此这篇关于Docker遇到502问题的排查与解决方法的文章就介绍到这了,更多相关Docker遇到502问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文