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状态码,请求排查原因并给出解决方法。
问题原因
- 协议不匹配:Nginx使用
proxy_pass进行HTTP代理,但PHP-FPM是FastCGI协议服务,无法通过HTTP协议直接通信,导致连接失败。 - 上游端口错误:负载均衡配置中指向的
9002/9003是宿主机到容器的映射端口,Docker内部网络中应使用PHP-FPM容器的内部端口9000。 - 冗余配置冲突:挂载到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
相关产品推荐
相关产品推荐

