两个Docker容器间的异常通信问题求助
问题原因与解决方案
1. 先排查基础拼写错误
你贴出的容器B的test_b.php代码里用了file_get_content,但PHP的正确函数是file_get_contents(末尾多一个s)。如果实际代码真的写错了,会触发函数不存在的错误,但你描述的是超时,大概率是输入时的笔误,不过还是先确认下代码正确性。
2. 核心原因:Apache进程死锁
这是导致超时的最可能因素:
- 当你访问容器A的
test_comm.php时,A的Apache会启动一个进程处理请求,该进程通过file_get_contents调用B的test_b.php; - B的Apache收到请求后,启动一个进程处理
test_b.php,该进程又去调用A的test_a.php; - 此时A的Apache需要新的进程来处理B的请求,但如果A的Apache可用进程数不足(比如默认配置下进程数刚好被占满,或测试环境进程数设置极小),就会陷入死锁:A的第一个进程在等B的响应,B的进程在等A的响应,A没有空闲进程处理B的请求,最终导致超时。
而直接在B里调用test_b.php时,B的进程请求A,此时A有空闲进程能处理,所以正常返回。
3. 潜在隐患:Docker服务名称冲突
你的两个docker-compose配置里,服务名都叫php,且在同一个mynetwork网络中。Docker同一网络内,服务的默认DNS别名就是服务名,这意味着两个容器的别名都是php——如果用http://php访问,DNS可能随机解析到任意一个容器,导致访问混乱。不过你说直接在B里调用能正常访问A,说明你实际用的是A的容器全名(比如a_php_1),所以这不是当前超时的直接原因,但建议修改服务名避免后续问题。
解决方法
- 确认PHP函数名:确保使用
file_get_contents; - 调整Apache进程数:
- 进入容器A,编辑
/etc/apache2/mods-available/mpm_prefork.conf(prefork模式下),提高MaxRequestWorkers的值(默认一般是150,测试环境可适当调高); - 重启Apache:
service apache2 restart;
- 进入容器A,编辑
- 修改docker-compose服务名:
- 把A的服务名改成
php-a,B的改成php-b,之后可以直接用http://php-a和http://php-b互相访问,避免DNS解析冲突。
- 把A的服务名改成
内容的提问来源于stack exchange,提问作者yeahman
相关产品推荐
相关产品推荐

