首页 > 解决方案 > 如何配置 Nginx 进行负载均衡

问题描述

我正在学习负载平衡的基础知识,Nginx下面是具有 3 个包含(2 个应用程序和 1 个 nginx)的示例应用程序

在此处输入图像描述

app1并且可以分别app2访问127.0.0.1:5001127.0.0.1:5002,但是当我打电话nginx127.0.0.1:8081我收到错误502 Bad Gateway

Nginx 容器日志

2021/02/25 10:36:33 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5001/", host: "0.0.0.0:8081", referrer: "http://0.0.0.0:9000/"
2021/02/25 10:36:33 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5002/", host: "0.0.0.0:8081", referrer: "http://0.0.0.0:9000/"
172.19.0.1 - - [25/Feb/2021:10:36:33 +0000] "GET / HTTP/1.1" 502 559 "http://0.0.0.0:9000/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"
2021/02/25 10:36:33 [error] 8#8: *1 no live upstreams while connecting to upstream, client: 172.19.0.1, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://loadbalancer/favicon.ico", host: "0.0.0.0:8081", referrer: "http://0.0.0.0:8081/"
172.19.0.1 - - [25/Feb/2021:10:36:33 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://0.0.0.0:8081/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"

以下是相关文件

应用 1 和应用 2:Dockerfile

应用程序 1:app.y

应用 2:app.y

nginx.conf

http {

    upstream loadbalancer {
        server 127.0.0.1:5001 weight=6;
        server 127.0.0.1:5002 weight=4;
    }

    server {
        location / {
            proxy_pass http://loadbalancer/;
        }
    }

}

events {
  
}

码头工人-compose.yml

version: '3.3'

services:
  
  # Application 1
  app1:
    build: ./app1         
    image: "app1:latest"   
    container_name: app1
    ports:
      - "5001:5000"
    networks:
      - net1
  
  # Application 2
  app2:
    build: ./app2
    image: "app2:latest"
    container_name: app2
    ports:
      - "5002:5000"
    networks:
      - net1

  # Nginx
  nginx:
    build: ./nginx
    image: "nginx:latest"
    container_name: nginx 
    ports:
      - "8081:80"
    depends_on:
      - app1
      - app2
    networks:
      - net1

networks:
  net1:
    external: true

标签: pythondockernginxflaskdocker-compose

解决方案


应用程序中的容器位于网络内它们自己的 IP 地址上,可以通过容器名称解析。

我已经重新创建了您的案例(由于您没有分解 nginx 构建,因此进行了少量修改,所以我使用了 ubuntu 容器并修改了 net1 由创建docker-compose)并连接到 nginx 容器。安装pingnetcat工具后:

CONTAINER ID   IMAGE                                 COMMAND                  CREATED         STATUS                     PORTS                    NAMES
d29b2a96a843   ubuntu:20.04                          "/bin/bash"              3 minutes ago   Up 3 minutes               0.0.0.0:8081->80/tcp     nginx
0200de2170a0   test-ng                               "python3 app.py"         3 minutes ago   Up 3 minutes               0.0.0.0:5001->5000/tcp   app1
0f1bd788a962   test-ng                               "python3 app.py"         3 minutes ago   Up 3 minutes               0.0.0.0:5002->5000/tcp   app2
root@d29b2a96a843:/# ping app1
PING app1 (172.21.0.2) 56(84) bytes of data.
64 bytes from app1.test_net1 (172.21.0.2): icmp_seq=1 ttl=64 time=0.126 ms
64 bytes from app1.test_net1 (172.21.0.2): icmp_seq=2 ttl=64 time=0.103 ms 
^C
--- app1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.103/0.114/0.126/0.011 ms
root@d29b2a96a843:/# ping app2
PING app2 (172.21.0.3) 56(84) bytes of data.
64 bytes from app2.test_net1 (172.21.0.3): icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from app2.test_net1 (172.21.0.3): icmp_seq=2 ttl=64 time=0.109 ms
^C
--- app2 ping statistics ---

为了进一步测试,我曾经nc连接应用程序

root@d29b2a96a843:/# nc app1 5000
GET /

"App #1"
^C
root@d29b2a96a843:/# nc app2 5000
GET /

"App #1"
^C
root@d29b2a96a843:/# nc localosht 5001
nc: getaddrinfo for host "localosht" port 5001: Name or service not known
root@d29b2a96a843:/# nc localosht 5002
nc: getaddrinfo for host "localosht" port 5002: Name or service not known

所以,总而言之,你没有5001在你的 ngingx 容器内的端口上运行 app1(除非你有一些net1你没有共享的“异国情调”设置)。这就是nginx抛出错误的no live upstreams while connecting to upstream原因,因为它找不到在localhost提供的 (127.0.0.1) 上打开的端口 5001 和 5002。

为了使您的示例正常工作,最简单的方法是nginx.conf按如下方式修改配置:

http {

    upstream loadbalancer {
        server app1:5000 weight=6;
        server app2:5000 weight=4;
    }

    server {
        location / {
            proxy_pass http://loadbalancer/;
        }
    }

}

events {
  
}

推荐阅读