You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx+Docker负载均衡网关报502,上游连接被拒绝问题求助

问题描述

终端报错信息

2023/07/31 09:30:16 [error] 23#23: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.21.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://192.168.21.3:9002/", host: "192.168.21.4:84"
2023/07/31 09:30:16 [error] 23#23: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.21.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://192.168.21.2:9003/", host: "192.168.21.4:84"
192.168.21.1 - - [31/Jul/2023:09:30:16 +0000] "GET / HTTP/1.1" 502 559 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
2023/07/31 09:30:16 [error] 23#23: *3 no live upstreams while connecting to upstream, client: 192.168.21.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://php-apps/favicon.ico", host: "192.168.21.4:84", referrer: "http://192.168.21.4:84/"
192.168.21.1 - - [31/Jul/2023:09:30:16 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://192.168.21.4:84/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"

Nginx负载均衡配置(nginx.conf)

worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;

    # 负载均衡配置
    upstream php-apps {
        server php-app1:9002;
        server php-app2:9003;
    }

    server {
        listen 84;
        server_name localhost;

        location / {
            proxy_pass http://php-apps;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

额外Nginx配置文件

app1.conf

http {
    server {
        listen 9002;
        server_name php-app1;
        root /var/www/app1/html;

        index index.php;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            fastcgi_pass php-app1:9000;
            fastcgi_index index.php;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

app2.conf

http {
    server {
        listen 9003;
        server_name php-app2;
        root /var/www/app2/html;

        index index.php;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            fastcgi_pass php-app2:9000;
            fastcgi_index index.php;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

Docker Compose配置

version: '3'

services:
  nginx-lb:
    build: 
      context: ./nginx
    ports:
      - "84:84"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/app1-config/app1.conf:/etc/nginx/conf.d/app1.conf
      - ./nginx/app2-config/app2.conf:/etc/nginx/conf.d/app2.conf
    depends_on:
      - php-app1
      - php-app2
    networks:
      my-test-network:
#        ipv4_address: 192.168.21.2
  php-app1:
    image: php:fpm
    volumes:
      - ./app1/html:/var/www/html
    ports:
      - "9002:9000"
    networks:
      my-test-network:
#       ipv4_address: 192.168.21.3
  php-app2:
    image: php:fpm
    volumes:
      - ./app2/html:/var/www/html
    ports:
      - "9003:9000"
    networks:
      my-test-network:
#        ipv4_address: 192.168.21.4
networks:
  my-test-network:
    driver: bridge
#    ipam:
#      config:
#       - subnet: 192.168.21.0/24

问题

使用Nginx作为负载均衡器搭配Docker部署PHP-FPM应用时,出现上游连接被拒绝错误,返回502状态码,请求排查原因并给出解决方法。


问题原因

  1. 协议不匹配:Nginx使用proxy_pass进行HTTP代理,但PHP-FPM是FastCGI协议服务,无法通过HTTP协议直接通信,导致连接失败。
  2. 上游端口错误:负载均衡配置中指向的9002/9003是宿主机到容器的映射端口,Docker内部网络中应使用PHP-FPM容器的内部端口9000。
  3. 冗余配置冲突:挂载到Nginx的app1.conf/app2.conf在容器内开启了额外的server监听,属于冗余配置,会导致Nginx内部逻辑混乱。

解决方法

1. 修正Nginx负载均衡配置

将HTTP代理改为FastCGI转发,同时修正上游端口为容器内部的9000:

worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;

    # 负载均衡指向PHP-FPM容器内部端口9000
    upstream php-apps {
        server php-app1:9000;
        server php-app2:9000;
    }

    server {
        listen 84;
        server_name localhost;

        # 统一设置根目录,确保与PHP容器挂载路径一致
        root /var/www/html;
        index index.php;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        # 通过FastCGI转发PHP请求到上游
        location ~ \.php$ {
            fastcgi_pass php-apps;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            # 传递必要的请求头
            fastcgi_param Host $host;
            fastcgi_param X-Real-IP $remote_addr;
            fastcgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
            fastcgi_param X-Forwarded-Proto $scheme;
        }
    }
}

2. 移除冗余配置

修改Docker Compose配置,删除Nginx容器挂载的app1.conf和app2.conf:

version: '3'

services:
  nginx-lb:
    build: 
      context: ./nginx
    ports:
      - "84:84"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - php-app1
      - php-app2
    networks:
      my-test-network:
  php-app1:
    image: php:fpm
    volumes:
      - ./app1/html:/var/www/html
    ports:
      - "9002:9000"
    networks:
      my-test-network:
  php-app2:
    image: php:fpm
    volumes:
      - ./app2/html:/var/www/html
    ports:
      - "9003:9000"
    networks:
      my-test-network:
networks:
  my-test-network:
    driver: bridge

3. 检查PHP代码目录

确保./app1/html和./app2/html目录下存在index.php文件,且文件权限允许PHP-FPM容器读取。

4. 重启服务

执行命令重启所有容器:

docker-compose down
docker-compose up -d

验证

  • 访问http://192.168.21.4:84,确认正常返回PHP页面
  • 查看Nginx错误日志,确认无连接错误:
docker exec -it $(docker ps -q --filter name=nginx-lb) cat /var/log/nginx/error.log

内容的提问来源于stack exchange,提问作者Taibh Khalid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 10:05:52