必须将所有php-fpm服务与nginx定义在同一docker-compose.yml中并加入同一自定义网络,否则nginx无法通过service名(如php1:9000)解析后端地址;upstream需显式配置server条目并配合ip_hash或least_conn等策略,同时各php-fpm容器须隔离配置、日志及socket路径以确保负载均衡真正生效。

docker-compose.yml 里配好多个 php-fpm 实例 + nginx 的 upstream,才能真正跑起来负载均衡。单靠堆容器没用,Nginx 必须明确知道后端有哪些 PHP-FPM 地址,且容器间网络要通。
为什么 nginx 容器里 fastcgi_pass php1:9000 会报 host not found
这是最常卡住的点:Docker Compose 默认为每个 service 创建独立的 DNS 名称,但前提是它们在同一个 networks 下,且名称要和 service 名完全一致。
-
php1、php2这些 service 名必须全部定义在同一个docker-compose.yml文件中(不能拆成多个文件或用extends) - 所有涉及通信的 service(包括
nginx和所有php-fpm)必须显式声明加入同一自定义网络,例如:networks: - app-net -
nginx配置里的upstream fpm_servers { server php1:9000; server php2:9000; }才能被正确解析——否则 Nginx 启动时就找不到 host,直接失败 - 别用
links:,它已废弃,且不保证 DNS 解析顺序
upstream 中要不要加 ip_hash 或 least_conn
取决于你的 PHP 应用是否带状态。无 session 共享的纯 API 服务推荐 least_conn;有登录态、依赖本地 session 文件的场景,必须加 ip_hash,否则用户刷新就登出。
-
ip_hash:客户端 IP 固定打到同一个 PHP-FPM 实例,适合 session 存本地文件的旧项目 -
least_conn:把请求发给当前连接数最少的实例,适合无状态 API 或 session 存 Redis 的新架构 - 别用默认轮询(round-robin),它不考虑后端负载,容易压垮某台
- 记得在
upstream块里加keepalive 32;,复用 TCP 连接,避免频繁建连开销
PHP-FPM 容器之间共享代码目录但配置要隔离
代码可以挂载同一份(比如 ./src:/var/www/html),但每个 PHP-FPM 实例的配置必须独立,否则一个改崩了全崩。
- 每个
php-fpmservice 的volumes要单独映射自己的www.conf,例如:./php1/www.conf:/usr/local/etc/php-fpm.d/www.conf -
pm.max_children建议按宿主机 CPU 核数设,比如 4 核机器,两个 PHP-FPM 实例各设10,别都设20,否则总并发超限 - 日志路径也要分开挂载,否则多个容器写同一个
error.log会乱序或覆盖:./logs/php1:/var/log/php-fpm - 如果用了 Unix socket(推荐),确保 socket 路径是 volume 挂载的,且权限为
www-data:www-data,否则 Nginx 访问不到
如何验证负载均衡真正在工作
光看 docker-compose ps 全绿没用,得确认请求确实分发到了不同实例。
- 在每个 PHP-FPM 容器的
www.conf里加一行:env[HOSTNAME] = php1(对应改成php2等),然后 PHP 里echo $_SERVER['HOSTNAME']; - 用
curl -s http://localhost | grep HOSTNAME多刷几次,观察输出是否在php1/php2之间切换 - 查 Nginx access log:
docker-compose logs -f nginx | grep "GET.*\.php",看每条请求的upstream_addr字段是不是轮着出现不同地址 - 如果始终只打到一个 PHP 实例,先检查
upstream是否写了down或backup,再检查该实例的php-fpm日志里有没有ERROR: unable to bind listening socket(端口被占)
实际部署时,最容易被忽略的是 PHP-FPM 实例之间的资源竞争和日志混杂。哪怕配置完全一样,两个容器共用一个 www.conf 文件,改个参数就得重启全部,排查问题时也分不清哪条日志来自哪个实例。把配置、日志、socket 路径全拆开,才是可维护的起点。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











