前情提要:本篇博客详细介绍了使用Nginx配置七层负载均衡(通过http反向代理负载均衡)和四层负载均衡(tcp/udp)的全部流程。
一、Nginx配置http反向代理负载均衡
Nginx 可以基于ngx_http_upstream_module模块提 供服务器分组转发、权重分配、状态监测、调度算法等高级功能
官方文档: https://nginx.org/en/docs/http/ngx_http_upstream_module.html
1.1 http upstream的配置参数
- 配置模板示例
cpp
#自定义一组服务器,配置在http块内
upstream name {
server .....
......
}
#示例
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
- server支持的parameters
cpp
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行 检测多少次,如果都失败就标记为 不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健 康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔 再次进行检测是否恢复可用,如 果发现可用,则将后端服务器参与调度,默认为10秒
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down #标记为down状态,可以平滑下线后端服务器
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启nginx
- hash计算
cpp
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
cpp
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
cpp
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
cpp
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
1.2 反向代理负载均衡示例:后端多台web服务器
配置示例
cpp
# 编辑主配置文件
[root@Nginx ~]# vim /usr/local/nginx/conf/nginx.conf
events {
worker_connections 10000; # 每个worker进程允许同时打开的最大连接数为10000
use epoll; # 使用epoll事件驱动模型(Linux下性能最优)
accept_mutex on; # 开启互斥锁,多个worker进程轮流接受新连接,避免"惊群效应"
multi_accept on; # 允许每个worker进程一次接受多个新连接
} # 最大并发连接数 ≈ worker进程数 × worker_connections
# 编辑子配置文件
[root@Nginx ~]# vim /usr/local/nginx/conf/conf.d/loadbalance.conf
upstream webserver {
server 172.25.254.11:80 weight=1 fail_timeout=15s max_fails=3;
server 172.25.254.12:80 weight=1 fail_timeout=15s max_fails=3;
server 172.25.254.10:8888 backup;
}
server {
listen 80;
server_name www.doubledragon.org;
location ~ / {
proxy_pass http://webserver;
}
}
[root@Nginx ~]# systemctl restart nginx
访问测试
cpp
[root@Nginx ~]# curl www.doubledragon.org
172.25.254.11-RS3
[root@Nginx ~]# curl www.doubledragon.org
172.25.254.12-RS4
[root@Nginx ~]# curl www.doubledragon.org
172.25.254.11-RS3
[root@Nginx ~]# curl www.doubledragon.org
172.25.254.12-RS4
二、Nginx配置四层负载均衡
Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于 DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp 负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、 调度算法等高级功能。
如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块
官方文档: https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
2.1 tcp负载均衡配置参数
配置参数示例
cpp
stream {
#定义stream相关的服务
Context:main
upstream backend {
#定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns {
#定义后端服务器
server 10.0.0.1:53; #定义具体server
server dns.example.com:53;
}
server {
#定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
}
2.2 tcp负载均衡示例:mysql服务器的负载均衡
后端服务器安装mariadb
环境配置
cpp
# RS3,RS4均安装mariadb
[root@RS4 ~]# dnf install mariadb-server -y
# 编辑mariadb配置文件配置server-id
[root@RS3 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=12
# 启动服务并创建远程连接用户
[root@RS4 ~]# systemctl enable --now mariadb
MariaDB [(none)]> create user dragon@'%' identified by '123';
MariaDB [(none)]> grant all on *.* to dragon@'%';
配置示例
cpp
# 编辑主配置文件
[root@Nginx ~]# vim /usr/local/nginx/conf/nginx.conf
stream {
upstream mysql_server {
server 172.25.254.11:3306 max_fails=3 fail_timeout=30s;
server 172.25.254.12:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.10:3306;
proxy_pass mysql_server;
proxy_connect_timeout 30s;
proxy_timeout 300s;
}
}
[root@Nginx ~]# nginx -s reload
访问测试
cpp
[root@Nginx ~]# mysql -udragon -p123 -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 11 |
+-------------+
[root@Nginx ~]# mysql -udragon -p123 -h172.25.254.10 -e "select @@server_id"
\+-------------+
| @@server_id |
+-------------+
| 12 |
+-------------+
# 可见可以成功实现负载均衡
# 在RS3停止mysql服务后再访问
[root@RS3 ~]# systemctl disable --now mariadb
[root@Nginx ~]# mysql -udragon -p123 -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 12 |
+-------------+
[root@Nginx ~]# mysql -udragon -p123 -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 12 |
+-------------+
2.3 udp负载均衡示例:DNS服务器的负载均衡
环境配置
cpp
# RS3 RS4均做以下操作
[root@RS3 ~]# dnf install bind -y
# 编辑dns服务的配置文件
[root@RS4 ~]# vim /etc/named.conf
options {
// listen-on port 53 { 127.0.0.1; };
// listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
// allow-query { localhost; };
dnssec-validation no; # 注意该参数配置文件中自带,需要注意不要写重复
[root@RS4 ~]# vim /etc/named.rfc1912.zones
zone "doubledragon.org" IN {
type master;
file "doubledragon.org.zone";
allow-update { none; };
};
[root@RS4 ~]# cd /var/named/
[root@RS4 named]# cp -p named.localhost doubledragon.org.zone
[root@RS4 named]# vim doubledragon.org.zone
$TTL 1D
@ IN SOA dns.doubledragon.org. rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS dns.doubledragon.org.
dns A 172.25.254.11 # 该处写RS主机的IP
[root@RS4 ~]# systemctl enable --now named
nginx配置示例
cpp
# 编辑主配置文件
[root@Nginx ~]# vim /usr/local/nginx/conf/nginx.conf
upstream dns_server {
server 172.25.254.11:53 max_fails=3 fail_timeout=30s;
server 172.25.254.12:53 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.10:53 udp;
proxy_pass dns_server;
proxy_timeout 1s;
proxy_responses 1;
error_log logs/dns.log;
}
[root@Nginx ~]# nginx -s reload
访问测试
cpp
[root@Nginx ~]# dig dns.doubledragon.org @172.25.254.10
; <<>> DiG 9.16.23-RH <<>> dns.doubledragon.org @172.25.254.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9323
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: d953041067ab57bc0100000069c50cdc983f78699b1e89a7 (good)
;; QUESTION SECTION:
;dns.doubledragon.org. IN A
;; ANSWER SECTION:
dns.doubledragon.org. 86400 IN A 172.25.254.12 ###
;; Query time: 0 msec
;; SERVER: 172.25.254.10#53(172.25.254.10)
;; WHEN: Thu Mar 26 18:39:25 CST 2026
;; MSG SIZE rcvd: 93
[root@Nginx ~]# dig dns.doubledragon.org @172.25.254.10
; <<>> DiG 9.16.23-RH <<>> dns.doubledragon.org @172.25.254.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10858
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 72e011a967b868a90100000069c50cddc78ed6604d9f2ec2 (good)
;; QUESTION SECTION:
;dns.doubledragon.org. IN A
;; ANSWER SECTION:
dns.doubledragon.org. 86400 IN A 172.25.254.11 ###
;; Query time: 2 msec
;; SERVER: 172.25.254.10#53(172.25.254.10)
;; WHEN: Thu Mar 26 18:39:26 CST 2026
;; MSG SIZE rcvd: 93
通过测试结果可见两次DNS解析分别调度到了不同的DNS服务器
至此实验结束,成功完成了nginx的七层负载均衡和四层负载均衡的配置和案例。