Nginx实现HTTP和TCP负载均衡

2018-04-19|Categories: Cluster, Linux|Tags: |

Nginx负载均衡支持HTTP、TCP、UDP协议。

HTTP负载均衡

测试环境

IP 域名 用途 服务器应用程序 安装命令
172.16.125.71 c.com 反向代理服务器 Nginx (EPEL repo) yum install nginx
172.16.125.72 后端服务器 #72 httpd yum install httpd
172.16.125.73 后端服务器 #73 httpd yum install httpd
172.16.125.1 客户端

域名解析

以下操作在172.16.125.1机器上执行:

echo '172.16.125.71 www.c.com c.com' >> /etc/hosts

准备web页面

以下操作在172.16.125.72机器上执行:

echo 'Backend_72' > /var/www/html/index.html

以下操作在172.16.125.73机器上执行:

echo 'Backend_73' > /var/www/html/index.html

配置Nginx

以下操作在172.16.125.71机器上执行:

upstream backend {
    server 172.16.125.72 weight=2 max_fails=3 fail_timeout=30s;
    server 172.16.125.73;
    server 127.0.0.1 backup;
}
location / {
    proxy_pass http://backend;
}

max_fails配合fail_timeout可以对后端服务器做健康检查:

  • fail_timeout指定的时间内,与后端服务器通信失败达到max_fails指定的次数,就认为其不可用。
  • 后端服务器被判定为不可用之后,超过fail_timeout指定的时间,Nginx将重新尝试与其通信。

测试

$ sort <(for i in {1..21}; do curl --noproxy '*' -kLs c.com; done) | uniq -c
     14 Backend_72
      7 Backend_73
      
$ sort <(for i in {1..45}; do curl --noproxy '*' -kLs c.com; done) | uniq -c
     30 Backend_72
     15 Backend_73
     
$ sort <(for i in {1..99}; do curl --noproxy '*' -kLs c.com; done) | uniq -c
     66 Backend_72
     33 Backend_73

可以看到,在使用默认调度算法(RR)时,权重为2的后端服务器172.16.125.72被调度的次数是权重为1的服务器的2倍。

Nginx负载均衡调度算法

Nginx支持四种调度算法:

  • Round robin
    • 默认算法
    • 给后端服务器指定权重后就变成WRR
  • least_conn;
  • hash key [consistent];
    • 非常适合后端是缓存服务器的场景
    • 支持会话绑定
    • consistent表示使用一致性哈希算法(Consistent Hashing),如果后端服务器集群的数量经常发生变化,指定这个参数会非常有用
      • Nginx使用的一致性哈希算法是Ketama这种实现
  • ip_hash;
    • 仅支持HTTP负载均衡,不支持TCP负载均衡
    • 支持会话绑定

Nginx官方的《Choosing an NGINX Plus Load‑Balancing Technique》对每种算法的原理和各自的优劣做了详细的解释。

TCP负载均衡

TCP负载均衡适合那些不使用HTTP协议的请求,例如访问MariaDB数据库。

测试环境

IP 用途 服务器应用程序 安装命令
内网:172.16.125.71/24
外网:192.168.3.141/23
反向代理服务器 Nginx (EPEL repo) yum install nginx
172.16.125.72/24 后端服务器 #72 MariaDB 10.2.13 yum install MariaDB-server
172.16.125.73/24 后端服务器 #73 MariaDB 10.2.14 yum install MariaDB-server
192.168.2.107/23 客户端

准备后端MariaDB服务器

CentOS自带的MariaDB-server版本是5.5,若要安装最新的10.2版,必须先配置MariaDB官方yum仓库

安装完成之后,必须添加一个用于测试的MariaDB账号,在两台后端服务器上分别执行以下操作:

systemctl start mariadb
mysql
MariaDB [(none)]> create user 'test'@'172.16.125.%' identified by 'centos';
MariaDB [(none)]> flush privileges;

配置Nginx

# ...

stream {
    upstream db_servers {
        server 172.16.125.72:3306 weight=2;
        server 172.16.125.73:3306 ;
        least_conn;
    }
    server {
       # 此处必须监听外网地址,
       # 如果监听内网地址,客户端将无法访问!
        listen 192.168.3.141:3306;
        # listen 172.16.125.71:3306;
        proxy_pass db_servers;
    }
}

http {
    # ...
}

测试

在客户端192.168.2.107/23执行以下命令:

mysql -u test -p centos -h 192.168.3.141

两次执行的结果如下图,从图中红色区域的版本号可以看到,每次连接的是不同的数据库,证明TCP负载均衡已生效。

Leave A Comment