Docker 构建简单的 Nginx 负载均衡

基本配置

首先安装好 Docker ,其次需要在宿主机上配置一个 Nginx 作为反向代理服务器,Nginx 的安装配置过程可以参考网上众多资料。

配置 Docker

这里需要先获取 Nginx 的 Docker 镜像,我们这里采用比较简单的方法,直接从Docker Hub获取官方配置好的 Nginx 镜像,如果想要借助 Docker File 进行构建的,可以参考 Docker 安装 Nginx | 菜鸟教程

#此处使用 latest 将自动下载最新版本镜像
MacBook-Pro:~ User$ docker pull nginx:latest
latest: Pulling from library/nginx
6d827a3ef358: Pull complete 
1e3e18a64ea9: Pull complete 
556c62bb43ac: Pull complete 
Digest: sha256:6202beb06ea61f44179e02ca965e8e13b961d12640101fca213efbfd145d7575
Status: Downloaded newer image for nginx:latest

随后可以在 Docker 中查询镜像的情况。

MacBook-Pro:~ user$ docker images
REPOSITORY   TAG        IMAGE ID         CREATED         SIZE
nginx        latest     881bd08c0b08     7 days ago      109MB

在下载好 Docker 镜像之后,我们就可以开始做一些基本配置了,这次打算用 Docker 启动三个 Nginx 容器来模拟三台负载均衡服务器。首先可以在当前目录下建立一个文件夹,用于存放供 Docker 使用的 Nginx 配置文件和需要显示的页面。目录结构如下。

~/
  ----1/
    ----conf.d/
      ----test.conf
    ----www/
      ----test.html
  ----2/
    ----conf.d/
      ----test.conf
    ----www/
      ----test.html
  ----3/
    ----conf.d/
      ----test.conf
    ----www/
      ----test.html

其中,nginx 配置文件如下。

server {
    listen       8080;
    server_name  localhost;
 
    location / {
        root   /usr/share/nginx/html;
        index  test.html test.htm;
    }
}

准备好相关文件之后,接下来就开始启动 Nginx 容器。

docker run -p 8001:80 --name nginx1 -v $PWD/1/www:/usr/share/nginx/html -v $PWD/1/conf.d:/etc/nginx/conf.d -d nginx:latest

根据以上的命令和相关的目录结构,分别启动了三个 Nginx 容器,需要注意绑定不同的端口避免冲突。可以使用以下命令来查看容器的具体情况

MacBook-Pro:~ User$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
aa33da453b83        nginx:latest        "nginx -g 'daemon of…"   12 hours ago        Up 12 hours         80/tcp, 0.0.0.0:8003->8080/tcp   nginx1
f7d8e35fc9c1        nginx:latest        "nginx -g 'daemon of…"   12 hours ago        Up 12 hours         80/tcp, 0.0.0.0:8002->8080/tcp   nginx2
e66b7e9aa486        nginx:latest        "nginx -g 'daemon of…"   12 hours ago        Up 12 hours         80/tcp, 0.0.0.0:8001->8080/tcp   nginx3

配置宿主机 Nginx 反向代理

上面的过程配置好了三个 Nginx 容器来模拟真正接收请求的负载均衡服务器,下面将对宿主机上的 Nginx 进行配置进行反向代理。需要在 Nginx 配置文件目录下添加以下配置文件。

server {
    listen       80;
    server_name  localhost;
 
    location / {
        proxy_pass http://nginxgroup;
    }
}
 
upstream nginxgroup{
    server 127.0.0.1:8001 weight=1;
    server 127.0.0.1:8002 weight=2;
    server 127.0.0.1:8003 weight=3;
}

其中的 upstream 标签就是对 nginx 集群进行配置,通过 proxy_pass 参数,请求就会传递给这些服务器进行处理。其中 weight 参数设置了权重,权重越大,越容易被分配请求。随后就可以在浏览器中进行访问了,可以通过不同的html来进行区分正在连接哪个 Nginx 容器。

扩展

在 Nginx 中,有多种负载均衡的策略,主要有以下几条(部分策略需要插件支持):

  • 随机:通过系统随机函数等概率随机,根据后台服务器列表的大小值来随机选取其中一台进行访问。随着调用量的增大,实际效果越来越接近于平均分配流量到后台的每一台服务器。
  • 加权随机:即按权重设置随机概率,同随机法相似。
  • 轮询:将请求按顺序轮流分配到后台服务器上,均衡的对待每一台服务器,而不关心服务器实际的连接数和当前的系统负载。当服务器集群中各服务器的处理能力相同时,且每笔业务处理量差异不大时,最适合使用这种算法。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
  • 加权轮询:即为轮询中的每台服务器附加一定权重的算法。可为不同的后台服务器设置不同的权重,例如给配置高、负载低的机器分配更高的权重,使其能处理更多的请求,而配置低、负载高的机器,则给其分配较低的权重,降低其系统负载。比如服务器1权重1,服务器2权重2,服务器3权重3,则顺序为1-2-2-3-3-3-1-2-2-3-3-3-......
  • 哈希:哈希可根据 IP地址/地址段、URL 地址等信息,通过哈希函数计算得到一个哈希值,将此哈希值和服务器列表的大小进行取模运算,得到的结果便是要访问的服务器地址的序号。
  • 最小连接数:前面的方法都是请求次数的均衡,并不代表负载的均衡。最小连接数法比较灵活和智能,它是根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器。
  • 加权最小连接数:为最少连接算法中的每台服务器附加权重的算法,同最小连接数法相似,该算法事先为每台服务器分配处理连接的数量,并将客户端请求转至连接数最少的服务器上。
  • 最小响应时间:通过测试服务器的响应时间来进行分配