Docker-Compose容器内部发起HTTP请求出现502超时问题
Docker容器内代码请求超时,但curl正常的排查与解决
部署了3个Docker容器,主容器con_a需要向其他容器发起请求。con_a内部通过代码发起HTTP请求时收到502连接超时响应,但在控制台用curl命令发起请求却能正常工作。
Docker-compose.yml配置
version: "3" services: con_a: networks: - my_net con_b: container_name: con_b hostname: con_b ports: - "9200:9200" - "9300:9300" networks: - my_net con_c: container_name: con_c image: con_c hostname: con_c build: ./con_c ports: - "1337:1337" networks: - my_net networks: my_net: driver: bridge
con_a中的请求代码
response = requests.get("http://con_c:1337/health_check")
正常情况下该请求应返回“success”。
收到的错误响应
'<HEAD><TITLE>Connection timed out</TITLE></HEAD> <BODY BGCOLOR="white" FGCOLOR="black"><H1>Connection timed out</H1><HR> <FONT FACE="Helvetica,Arial"><B> Description: Connection timed out</B></FONT> <HR> <!-- default "Connection timed out" response (502) --> </BODY> '
排查与解决思路
1. 检查代码代理配置
requests库会自动读取容器内的代理环境变量,如果代理无法访问Docker内部网络,就会导致代码请求超时,但curl默认不加载代理配置。
- 临时禁用代理测试:
response = requests.get("http://con_c:1337/health_check", proxies={"http": None, "https": None}) - 检查容器内代理变量:执行
env | grep -i proxy,若存在HTTP_PROXY/HTTPS_PROXY变量,可删除或在代码中覆盖。
2. 验证con_c服务监听地址
如果con_c的应用仅监听127.0.0.1,则只能在容器内部访问,其他容器无法通过容器名连接。
- 进入con_c容器,执行
netstat -tulpn查看监听地址,确保是0.0.0.0:1337而非127.0.0.1:1337。 - 修改con_c的应用配置,让服务监听所有网卡地址。
3. 调整代码超时设置
代码中requests请求可能未设置超时,或超时时间过短,而curl默认超时更长。添加超时参数测试:
response = requests.get("http://con_c:1337/health_check", timeout=10)
4. 确认容器启动顺序
若con_a先于con_c启动,代码可能在con_c服务未就绪时发起请求,导致超时。
- 在docker-compose.yml中给con_a添加依赖:
con_a: networks: - my_net depends_on: - con_c - 更可靠的方式是在con_a的启动脚本中添加健康检查,等待con_c服务就绪后再启动应用。
5. 验证网络连通性
虽然curl能通,但可进一步确认网络状态:
- 在con_a容器内执行
ping con_c,确认DNS解析正常。 - 执行
telnet con_c 1337测试端口连通性,确保端口开放。
内容的提问来源于stack exchange,提问作者utulb
相关产品推荐
相关产品推荐

