健康检查与高可用¶
一. 健康检查¶
1. 环境设置¶
- 192.168.100.99 一号机
- 192.168.100.100 二号机
- 192.168.100.101 三号机
- 192.168.100.102 四号机
2. 设置环境¶
Ⅰ. 四台机器均安装nginx¶
[^_^] [root@1 ~]#mount /dev/sr0 /media/cdrom
[^_^] [root@1 ~]#dnf -y install nginx vim wget unzip
[^_^] [root@2 ~]#mount /dev/sr0 /media/cdrom
[^_^] [root@2 ~]#dnf -y install nginx vim wget unzip
[^_^] [root@3 ~]#mount /dev/sr0 /media/cdrom
[^_^] [root@3 ~]#dnf -y install nginx vim wget unzip
[^_^] [root@4 ~]#mount /dev/sr0 /media/cdrom
[^_^] [root@4 ~]#dnf -y install nginx vim wget unzip
Ⅱ. 在三号机上进行操作¶
a. 创建目录,然后写入网站内容
[root@3 ~]# mkdir -p /var/www/backend
[root@3 ~]# echo "This is wen 101" >/var/www/backend/index.html
b. 编写nginx配置文件
[root@3 ~]# vim /etc/nginx/conf.d/backend.conf
server {
listen 80;
server_name 192.168.100.101;
root /var/www/backend;
index index.html;
}
c. 语法检测,无误后启动服务
[root@3 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@3 ~]# systemctl start nginx
Ⅲ. 切换到四号机进行配置¶
[root@3 ~]# exit
注销
Connection to 192.168.100.101 closed.
[root@5 markdown-project]# ssh root@192.168.100.102
root@192.168.100.102's password:
Last login: Thu Jun 18 09:08:40 2026 from 192.168.100.103
a. 创建目录,然后写入网站内容
[^_^] [root@4 ~]#mkdir -p /var/www/backend
[^_^] [root@4 ~]#echo "This is wen 102" >/var/www/backend/index.html
b. 编写nginx配置文件
[^_^] [root@4 ~]#vim /etc/nginx/conf.d/backend.conf
server {
listen 80;
server_name 192.168.100.102;
root /var/www/backend;
index index.html;
}
c. 语法检测,无误后启动服务
[^_^] [root@4 ~]#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[^_^] [root@4 ~]#systemctl start nginx
[^_^] [root@4 ~]#exit
注销
Connection to 192.168.100.102 closed.
Ⅳ. 切换到一号机进行操作¶
a. 编写nginx配置文件
[root@5 markdown-project]# ssh root@192.168.100.99
root@192.168.100.99's password:
Last login: Thu Jun 18 09:10:29 2026 from 192.168.100.103
[root@1 ~]# vim /etc/nginx/conf.d/proxy-lab.conf
upstream backend_cluster {
server 192.168.100.101;
server 192.168.100.102;
}
server {
listen 80;
server_name 192.168.100.99;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host; #必须加上:传递原始域名(解决缺陷一)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#必须加上:传递真实客户端 IP
}
}
b. 语法检测,无误后启动服务
[root@1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@1 ~]# systemctl start nginx
[root@1 ~]# exit
注销
Connection to 192.168.100.99 closed.
Ⅴ. 访问验证¶
[root@5 markdown-project]# curl 192.168.100.99
This is wen 101
[root@5 markdown-project]# curl 192.168.100.99
This is wen 102
[root@5 markdown-project]# curl 192.168.100.99
This is wen 101
[root@5 markdown-project]# curl 192.168.100.99
This is wen 102
3. 被动健康检查¶
Ⅰ. 几个概念¶
- max_fails:在timeout时间范围内,运行后端服务器通讯失败的最大次数
- fails_timeout:后端服务器断开连接后的超时时间,默认为10s
- 0s 客户端请求 1 --> 超时 1 正常
2s 客户端请求2 --> 超时 2 正常
3s 客户端请求3 --> 超时 3 标记为down
3-13s 左右的的新(new包)请求跳过该主机 down(冷却中)
13s fail_timeout到期,重置计数器 0 恢复访问
关键点:
如果10s内没有第四个请求,计数器不会自动清零,直到有下一次请求失败时间才会在新的10s窗口重新计算。 如果10s内没有请求,则无法发现后端是否存活,这也是被动健康检查的致命问题。
Ⅱ. 实现步骤¶
a. 修改nginx一号机配置文件
[root@5 markdown-project]# ssh root@192.168.100.99
root@192.168.100.99's password:
Last login: Thu Jun 18 09:51:48 2026 from 192.168.100.103
[root@1 ~]# vim /etc/nginx/conf.d/proxy-lab.conf
upstream backend_cluster {
server 192.168.100.101 max_fails=3 fail_timeout=10s;
server 192.168.100.102 max_fails=3 fail_timeout=10s;
#最大失败次数3次,超时时间为10s。
}
server {
listen 80;
server_name 192.168.100.99;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host; #必须加上:传递原始域名(解决缺陷一)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#必须加上:传递真实客户端 IP
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
#如果所有服务器都失败,则向客户端返回 5XX 错误。
proxy_connect_timeout 2s;
#如果 2 秒内连接未建立成功,视为超时,会重试下一个后端服务器。
proxy_read_timeout 5s;
#定义 Nginx 向后端服务器发送请求后,等待其返回响应数据的超时时间。如果发送请求后5s内后端服务器没有返回任何结果,视为超时。会重试下一个后端服务器。
}
}
c. 语法检测无误后重启服务
[root@1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@1 ~]# systemctl reload nginx
[root@1 ~]# exit
注销
Connection to 192.168.100.99 closed.
d. 关闭3号机,然后进行验证
[root@5 markdown-project]# ssh root@192.168.100.101
root@192.168.100.101's password:
Last login: Thu Jun 18 09:50:32 2026 from 192.168.100.103
[root@3 ~]# systemctl stop nginx
[root@3 ~]# exit
注销
Connection to 192.168.100.101 closed.
[root@5 markdown-project]# curl 192.168.100.99
This is wen 102
[root@5 markdown-project]# curl 192.168.100.99
This is wen 102
[root@5 markdown-project]# curl 192.168.100.99
This is wen 102
4. 主动健康检查¶
Ⅰ. 升级nginx
a. 查看nginx版本和nginx安装过的模块
[root@5 ~]# nginx -v
nginx version: nginx/1.20.1
[root@5 ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 11.5.0 20240719 (Red Hat 11.5.0-14) (GCC)
built with OpenSSL 3.5.5 27 Jan 2026
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-compat --with-debug --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-cc-opt='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64-v2 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,-E'
b. 去GitHub拉取nginx_upstream_check_module模块,再去nginx官网拉取nginx-1.20.2版本并解压
[root@5 ~]# ssh root@192.168.100.99
root@192.168.100.99's password:
Last login: Thu Jun 18 10:16:41 2026 from 192.168.100.103
[root@1 ~]# wget https://nginx.org/download/nginx-1.20.2.tar.gz
--2026-06-18 10:49:24-- https://nginx.org/download/nginx-1.20.2.tar.gz
正在解析主机 nginx.org (nginx.org)...
3.125.197.172, 2a05:d014:5c0:2601::6, 2a05:d014:5c0:2600::6
正在连接 nginx.org (nginx.org)|3.125.197.172|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1062124 (1.0M) [application/octet-stream]
正在保存至: “nginx-1.20.2.tar.gz”
nginx-1.20.2.tar.gz 100%[=======================================================>] 1.01M 1.05MB/s 用时 1.0s
2026-06-18 10:49:32 (1.05 MB/s) - 已保存 “nginx-1.20.2.tar.gz” [1062124/1062124])
[root@1 ~]# git clone https://github.com/yaoweibin/nginx_upstream_check_module.git
正克隆到 'nginx_upstream_check_module'...
remote: Enumerating objects: 787, done.
remote: Counting objects: 100% (2/2), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 787 (delta 0), reused 0 (delta 0), pack-reused 785 (from 2)
接收对象中: 100% (787/787), 418.30 KiB | 756.00 KiB/s, 完成.
处理 delta 中: 100% (420/420), 完成.
[root@1 ~]# curl -o check_1.20.1+.patch -L "https://raw.githubusercontent.com/yaoweibin/nginx_upstream_check_module/37436e53457704e70cde82c00f6d8c51a5860e56/check_1.20.1%2B.patch"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8419 100 8419 0 0 7301 0 0:00:01 0:00:01 --:--:-- 7308
[root@1 ~]# ls
anaconda-ks.cfg check_1.20.1+.patch nginx-1.20.2.tar.gz
[root@1 ~]# tar -xf nginx-1.20.2.tar.gz
[root@1 ~]# ls
anaconda-ks.cfg nginx-1.20.2
check_1.20.1+.patch nginx-1.20.2.tar.gz
c. 安装打补丁命令和其他需要的环境
[root@1 ~]# dnf -y install patch gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
上次元数据过期检查:1:43:56 前,执行于 2026年06月18日 星期四 09时17分55秒。
软件包 patch-2.7.6-16.el9.x86_64 已安装。
软件包 pcre-8.44-4.el9.x86_64 已安装。
软件包 zlib-1.2.11-40.el9.x86_64 已安装。
软件包 openssl-1:3.2.2-6.el9_5.1.x86_64 已安装。
...
已升级:
glibc-2.34-270.el9_8.x86_64
glibc-common-2.34-270.el9_8.x86_64
glibc-devel-2.34-270.el9_8.x86_64
glibc-gconv-extra-2.34-270.el9_8.x86_64
glibc-headers-2.34-270.el9_8.x86_64
glibc-langpack-zh-2.34-270.el9_8.x86_64
libgcc-11.5.0-14.el9.x86_64
libgomp-11.5.0-14.el9.x86_64
openssl-1:3.5.5-4.el9_8.x86_64
openssl-libs-1:3.5.5-4.el9_8.x86_64
已安装:
annobin-12.92-1.el9.x86_64
cpp-11.5.0-14.el9.x86_64
gcc-11.5.0-14.el9.x86_64
gcc-plugin-annobin-11.5.0-14.el9.x86_64
libmpc-1.2.1-4.el9.x86_64
make-1:4.3-8.el9.x86_64
openssl-devel-1:3.5.5-4.el9_8.x86_64
openssl-fips-provider-1:3.5.5-4.el9_8.x86_64
pcre-cpp-8.44-4.el9.x86_64
pcre-devel-8.44-4.el9.x86_64
pcre-utf16-8.44-4.el9.x86_64
pcre-utf32-8.44-4.el9.x86_64
zlib-devel-1.2.11-40.el9.x86_64
完毕!
d. 打补丁
[root@1 ~]# cd /root/nginx-1.20.2
patch -p1 < /root/nginx_upstream_check_module/check_1.20.1+.patch
patching file src/http/modules/ngx_http_upstream_hash_module.c
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
patching file src/http/ngx_http_upstream_round_robin.h
e. 给新nginx设置模块
[root@1 nginx-1.20.2]# cp /root/nginx_upstream_check_module/ngx_http_upstream_check_module.c /root/nginx-1.20.2/src/http/modules/
[root@1 nginx-1.20.2]# cp /root/nginx_upstream_check_module/ngx_http_upstream_check_module.h /root/nginx-1.20.2/src/http/modules/
[root@1 nginx-1.20.2]# ./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body \
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/subsys/nginx \
--user=nginx --group=nginx \
--with-compat --with-debug \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--add-module=/root/nginx_upstream_check_module
f. 输入指令编译
[root@1 nginx-1.20.2]# make -j$(nproc)
make -f objs/Makefile
make[1]: 进入目录“/root/nginx-1.20.2”
...
make[1]: 离开目录“/root/nginx-1.20.2”
g. 停掉老版本nginx,用新版本nginx替换老版本,并重新检查语法
[root@1 nginx-1.20.2]# ls objs
autoconf.err nginx.8 ngx_mail_module_modules.c ngx_modules.c ngx_stream_module_modules.o
Makefile ngx_auto_config.h ngx_mail_module_modules.o ngx_modules.o ngx_stream_module.so
nginx ngx_auto_headers.h ngx_mail_module.so ngx_stream_module_modules.c src
[root@1 nginx-1.20.2]# cp ./objs/nginx /usr/sbin/nginx
cp:是否覆盖'/usr/sbin/nginx'? y
[root@1 nginx-1.20.2]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@1 nginx-1.20.2]# systemctl start nginx
[root@1 nginx-1.20.2]# ss -tuanp|grep nginx
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=16646,fd=6),("nginx",pid=16645,fd=6),("nginx",pid=16644,fd=6))
tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=16646,fd=7),("nginx",pid=16645,fd=7),("nginx",pid=16644,fd=7))
Ⅱ. 修改配置文件
[root@1 /]# vim /etc/nginx/conf.d/proxy-lab.conf
upstream backend_cluster {
server 192.168.100.101;
server 192.168.100.102;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
keepalive 16;
#interval 检查间隔时间,每 3 秒对每个后端执行一次健康检查。
#rise 恢复阈值:连续成功检查 2 次 后,将后端服务器标记为“健康”(可再次接收流量)
#fall 故障阈值:连续失败检查 5 次 后,将后端服务器标记为“不健康”,Nginx 将不再向其转发请求。
#timeout 单次检查的超时时间,单位毫秒。如果 2 秒内未收到响应,本次检查视为失败。
#type 检查协议类型为 HTTP。模块会向后端发送 HTTP 请求(默认 GET /)并根据响应状态码判断(2xx/3xx 为成功,其他为失败)。
#每个 Worker 进程为这个后端集群(backend_cluster)最多缓存 16 个空闲的 Keep-Alive 连接。
}
server {
listen 80;
server_name 192.168.100.99;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host; #必须加上:传递原始域名(解决缺陷一)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#必须加上:传递真实客户端 IP
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
#如果所有服务器都失败,则向客户端返回 5XX 错误。
proxy_connect_timeout 2s;
#如果 2 秒内连接未建立成功,视为超时,会重试下一个后端服务器。
proxy_read_timeout 5s;
#定义 Nginx 向后端服务器发送请求后,等待其返回响应数据的超时时间。如果发送请求后5s内后端服务器没有返回任何结果,视为超时。会重试下一个后端服务器。
}
location /status {
check_status;
access_log off;
allow 192.168.100.0/24;
deny all;
#/status只允许192.168.100.0/24网段访问,其他均拒绝
}
}
Ⅳ. 检查没有语法错误后重启服务
[root@1 nginx-1.20.2]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@1 nginx-1.20.2]# systemctl start nginx
Ⅵ. 验证
[root@1 nginx-1.20.2]# exit
注销
Connection to 192.168.100.99 closed.
[root@5 ~]# for i in {1..20}; do curl 192.168.100.99;done
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
This is wen 101
This is wen 102
Ⅶ 避免崩溃:避免keepalive_timeout时间过长导致到达文件描述符最高值,最终nginx崩溃
QPS低:100足够
高并发常见:QPS大于10000时,调整到1000~10000。
内部服务通讯:keepalive_timeout可设置为120s或者300s
继续修改1的配置文件
[root@1 ~]# vim /etc/nginx/conf.d/proxy-lab.conf
keepalive_requests 1000;
#设置长连接最多可以处理的请求为1000,访问数量大于1000时nginx关闭远程连接并建立新的连接
#keepalive_timeout 65;
#设置空连接,空连接保持打开时间的超时时间
upstream backend_cluster {
server 192.168.100.101;
server 192.168.100.102;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
#keepalive 16;
#interval 检查间隔时间,每 3 秒对每个后端执行一次健康检查。
#rise 恢复阈值:连续成功检查 2 次 后,将后端服务器标记为“健康”(可再次接收流量)
#fall 故障阈值:连续失败检查 5 次 后,将后端服务器标记为“不健康”,Nginx 将不再向其转发请求。
#timeout 单次检查的超时时间,单位毫秒。如果 2 秒内未收到响应,本次检查视为失败。
#type 检查协议类型为 HTTP。模块会向后端发送 HTTP 请求(默认 GET /)并根据响应状态码判断(2xx/3xx 为成功,其他为失败)。
#每个 Worker 进程为这个后端集群(backend_cluster)最多缓存 16 个空闲的 Keep-Alive 连接。
}
server {
listen 80;
server_name 192.168.100.99;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host; #必须加上:传递原始域名(解决缺陷一)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#必须加上:传递真实客户端 IP
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
#如果所有服务器都失败,则向客户端返回 5XX 错误。
proxy_connect_timeout 2s;
#如果 2 秒内连接未建立成功,视为超时,会重试下一个后端服务器。
proxy_read_timeout 5s;
#定义 Nginx 向后端服务器发送请求后,等待其返回响应数据的超时时间。如果发送请求后5s内后端服务器没有返回任何结果,视为超时。会重试下一个后端服务器。
}
location /status {
check_status;
access_log off;
allow 192.168.100.0/24;
deny all;
#/status只允许192.168.100.0/24网段访问,其他均拒绝
}
}
nginx作为调度器/反向代理的调度算法有:
- 轮询。默认调度算法。
- 加权轮询。每一个后端应用服务器的权重(weight)不同。
- 最少连接least_conn.
- 源地址哈希ip_hash。游戏最常用
二. 高可用¶
1. 修改1的Nginx配置文件¶
[root@1 ~]# vim /etc/nginx/conf.d/proxy-lab.conf
keepalive_requests 1000;
#设置长连接最多可以处理的请求为1000,访问数量大于1000时nginx关闭远程连接并建立新的连接
upstream backend_cluster {
server 192.168.100.101;
server 192.168.100.102;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
#interval 检查间隔时间,每3秒对每个后端执行一次健康检查。
#rise 恢复阈值:连续成功检查2次后,将后端服务器标记为“健康”(可再次接收流量)
#fall 故障阈值:连续失败检查5次后,将后端服务器标记为“不健康”,Nginx将不再向其转发请求。
#timeout 单次检查的超时时间,单位毫秒。如果2秒内未收到响应,本次检查视为失败。
#type 检查协议类型为 HTTP。模块会向后端发送 HTTP 请求(默认 GET /)并根据响应状态码判断(2xx/3xx 为成功,其他为失败)。
#每个 Worker 进程为这个后端集群(backend_cluster)最多缓存 16 个空闲的 Keep-Alive 连接。
keepalive 16; # ← 控制 Nginx → 后端的长连接池大小
}
server {
listen 80;
server_name 192.168.100.50;
#keepalive_requests 1000; # ← 控制客户端 → Nginx 的单连接请求数上限
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host; #必须加上:传递原始域名(解决缺陷一)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#必须加上:传递真实客户端 IP
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
#如果所有服务器都失败,则向客户端返回 5XX 错误。
proxy_connect_timeout 2s;
#如果 2 秒内连接未建立成功,视为超时,会重试下一个后端服务器。
proxy_read_timeout 5s;
#定义 Nginx 向后端服务器发送请求后,等待其返回响应数据的超时时间。如果发送请求后5s内后端服务器没有返回任何结果,视为超时。会重试下一个后端服务器。
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /status {
check_status;
access_log off;
allow 192.168.100.0/24;
deny all;
#/status只允许192.168.100.0/24网段访问,其他均拒绝
}
location /health { #健康检查
access_log off;
return 200 "OK\n";
}
}
2. 检查语法并重启Nginx¶
[root@1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@1 ~]# systemctl reload nginx
3. 传送配置文件到二号机¶
[root@1 ~]# scp /etc/nginx/conf.d/proxy-lab.conf root@192.168.100.100:/etc/nginx/conf.d
The authenticity of host '192.168.100.100 (192.168.100.100)' can't be established.
ED25519 key fingerprint is SHA256:fjIre3E5sRKwStOhIN2KbZTpEj4iQLZj2JQZWWnVi6U.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:1: 192.168.100.101
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.100' (ED25519) to the list of known hosts.
root@192.168.100.100's password:
proxy-lab.conf 100% 2077 3.4MB/s 00:00
4. 安装Keepalived¶
[root@1 ~]# ssh root@192.168.100.100
root@192.168.100.100's password:
Last login: Thu Jun 18 15:49:33 2026 from 192.168.100.103
[root@2 ~]# dnf -y install keepalived
[root@2 ~]# exit
注销
Connection to 192.168.100.100 closed.
5. 查看Nginx进程¶
[root@1 ~]# pgrep -x nginx
22242
26972
26973
6. 静默检查健康状态¶
[root@1 ~]# curl -s 127.0.0.1/health
OK
[root@1 ~]# curl -s -f 127.0.0.1/health
OK
#通过返回状态码判断返回值是不是非零值
[root@1 ~]# curl -s -f -m 2 127.0.0.1/health
OK
#设置curl操作时间为2s
7. 编写监控脚本¶
[root@1 ~]# vim /usr/local/bin/check_nginx.sh
#!/bin/bash
if ! pgrep -x "nginx" > /dev/null;
then
exit 1
fi
#如果nginx进程号不存在,则退出并返回1
if ! ss -tln|grep -q ":80";
then
exit 1
fi
#如果端口80没有被占用,则退出并返回1
if curl -s -f -m 2 http://127.0.0.1/health > /dev/null;
then
exit 0
else
exit 1
fi
#如果curl http://127.0.0.1/health成功则返回0,否则返回1
[root@1 ~]# chmod +x /usr/local/bin/check_nginx.sh
[root@1 ~]# /usr/local/bin/check_nginx.sh
[root@1 ~]# echo $?
0
8. 配置一号机Keepalived¶
[root@1 ~]# vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
#failover@firewall.loc
#sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
#smtp_server 192.168.200.1
#smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2
timeout 2
weight -20
fall 3
rise 3
}
vrrp_instance VI_1 {
state MASTER
interface ens160
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass wensir
}
virtual_ipaddress {
192.168.100.50/24 dev ens160
}
track_script {
chk_nginx
}
unicast_src_ip 192.168.100.99
unicast_peer {
192.168.100.100
}
}
9. 传送脚本到二号机¶
[root@1 ~]# scp /usr/local/bin/check_nginx.sh root@192.168.100.100:/usr/local/bin/check_nginx.sh
root@192.168.100.100's password:
check_nginx.sh 100% 410 260.1KB/s 00:00
10. 启动Keepalived服务¶
[root@1 ~]# systemctl start keepalived
[root@2 ~]# systemctl start keepalived
11. 二号机升级Nginx¶
[root@1 ~]# scp check_1.20.1+.patch root@192.168.100.100:/root/
[root@1 ~]# scp -r nginx_upstream_check_module root@192.168.100.100:/root/
[root@1 ~]# ssh root@192.168.100.100
root@192.168.100.100's password:
Last login: Thu Jun 18 16:46:31 2026 from 192.168.100.103
[root@2 ~]# ls
anaconda-ks.cfg check_1.20.1+.patch nginx-1.20.2.tar.gz nginx_upstream_check_module
[root@2 ~]# tar -xf nginx-1.20.2.tar.gz
[root@2 ~]# dnf -y install patch gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
[root@2 ~]# cd /root/nginx-1.20.2
[root@2 nginx-1.20.2]# patch -p1 < /root/nginx_upstream_check_module/check_1.20.1+.patch
[root@2 nginx-1.20.2]# cp /root/nginx_upstream_check_module/ngx_http_upstream_check_module.c /root/nginx-1.20.2/src/http/modules/
[root@2 nginx-1.20.2]# cp /root/nginx_upstream_check_module/ngx_http_upstream_check_module.h /root/nginx-1.20.2/src/http/modules/
[root@2 nginx-1.20.2]# ./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body \
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/subsys/nginx \
--user=nginx --group=nginx \
--with-compat --with-debug \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--add-module=/root/nginx_upstream_check_module
[root@2 nginx-1.20.2]# make -j$(nproc)
[root@2 nginx-1.20.2]# ls objs
addon autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src
[root@2 nginx-1.20.2]# cp ./objs/nginx /usr/sbin/nginx
cp:是否覆盖'/usr/sbin/nginx'? y
[root@2 nginx-1.20.2]# systemctl start nginx
[root@2 nginx-1.20.2]# ss -tuanp|grep nginx
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=17828,fd=6),("nginx",pid=17827,fd=6),("nginx",pid=17826,fd=6))
tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=17828,fd=7),("nginx",pid=17827,fd=7),("nginx",pid=17826,fd=7))
12. 配置二号机Keepalived¶
[root@2 ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
#failover@firewall.loc
#sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
#smtp_server 192.168.200.1
#smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2
timeout 2
weight -20
fall 3
rise 3
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass wensir
}
virtual_ipaddress {
192.168.100.50/24 dev ens160
}
track_script {
chk_nginx
}
unicast_src_ip 192.168.100.100
unicast_peer {
192.168.100.99
}
}
[root@2 ~]# systemctl restart keepalived
**** nginx代理服务器1和2配置文件的区别
nginx配置文件相同,keepalive配置文件有四处不同
| 字段 | 一号机 (MASTER) | 二号机 (BACKUP) |
|---|---|---|
state |
MASTER |
BACKUP |
priority |
100 |
90 |
unicast_src_ip |
192.168.100.99 |
192.168.100.100 |
unicast_peer |
192.168.100.100 |
192.168.100.99 |