Nginx健康检查,负载均衡后端节点监控
Nginx做负载均衡时,如果某个后端节点宕机,默认不会自动踢出,请求仍可能被转发过去,导致用户看到502错误。
本文讲解如何配置Nginx健康检查,实现对后端节点的自动监控与故障隔离,并给出验证方法。
理解Nginx的健康检查机制
Nginx本身只带被动健康检查:当某个后端连续失败达到max_fails次数,并在fail_timeout时间内,Nginx会暂时把它标记为不可用,不再转发请求。
超过fail_timeout后,Nginx会再次尝试。
主动健康检查需要第三方模块nginx_upstream_check_module,它会定期向后端发探测请求,主动判断节点是否存活。
生产环境建议根据业务容忍度选择:对故障切换要求高就用主动检查,否则被动检查也能应付多数场景。
前置准备与环境确认
先确认Nginx版本和编译参数,决定后续是直接改配置还是需要重新编译。
nginx -V 2>&1 | grep -o 'with-http_upstream_check_module'
如果没有输出,说明当前Nginx未编译主动检查模块。
被动检查不需要额外模块,直接编辑配置文件即可。
查看Nginx配置文件路径:
nginx -t
输出会显示主配置文件位置,通常是/etc/nginx/nginx.conf或/usr/local/nginx/conf/nginx.conf。
配置被动健康检查
在http块内定义upstream,设置失败阈值和超时时间。
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup;
}
关键参数说明:
max_fails=3:连续失败3次后标记节点不可用。fail_timeout=30s:30秒内失败次数达到阈值则踢出,30秒后重新尝试。backup:备用节点,仅当所有主节点不可用时才转发。
把upstream应用到server块:
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
}
proxy_next_upstream让Nginx在遇到指定错误时自动换下一个节点,配合被动检查能减少用户感知的故障。
启用主动健康检查
如果编译了nginx_upstream_check_module,可以在upstream中添加检查指令。
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
参数含义:
interval=3000:每3秒探测一次。rise=2:连续成功2次标记为健康。fall=3:连续失败3次标记为不健康。timeout=1000:探测超时1秒。type=http:使用HTTP探测。
后端需要提供一个健康检查接口,例如/health返回200状态码。
查看后端节点状态
主动检查模块自带状态页面,在server块中添加:
location /nstatus {
check_status;
allow 127.0.0.1;
deny all;
}
重载Nginx后访问http://你的服务器IP/nstatus,可以看到每个后端节点的状态、存活次数和失败次数。
被动检查没有内置状态页,但可以通过Nginx错误日志观察:
tail -f /var/log/nginx/error.log | grep upstream
日志中出现upstream server temporarily disabled表示节点已被踢出。
避坑与常见问题
误区一:max_fails=0表示不检查
max_fails=0是关闭被动检查,不是无限重试。需要监控就设置大于0的值。
误区二:fail_timeout设得太短
如果后端只是短暂抖动,fail_timeout太短会导致频繁踢出和恢复,建议根据业务响应时间设置10s以上。
误区三:主动检查未编译模块
直接写check指令会报unknown directive "check",必须确认模块已编译或使用OpenResty等自带模块的版本。
后端返回403/404导致误判
check_http_expect_alive默认只认2xx和3xx,如果健康接口返回401或403,需要调整预期状态码,否则健康节点会被误踢。
验证健康检查是否生效
完成配置后,按以下步骤验证:
- 重载Nginx:
nginx -s reload - 访问状态页或查看错误日志,确认所有节点显示为up。
- 手动停掉一个后端服务:
systemctl stop your-app - 观察状态页,等待
fall次数达到后节点变为down。 - 用
curl反复请求Nginx入口,确认请求只落在健康节点上,没有502。 - 重启后端服务,等待
rise次数达到后节点恢复up。
如果第3步后状态页没有变化,检查interval和fall是否设置过大,或探测请求是否被防火墙拦截。
常见疑问
Nginx被动检查和主动检查能同时用吗?
可以。主动检查负责定期探测,被动检查作为兜底,两者不冲突。
健康检查会影响性能吗?
主动检查会定期发请求,但间隔通常为秒级,对后端压力很小。被动检查无额外开销。
后端是HTTPS,健康检查怎么写?
主动检查使用type=https,并配置check_http_send发送HTTPS请求,同时确保后端证书有效。
节点恢复后多久重新接入?
被动检查在fail_timeout后重新尝试;主动检查在连续成功rise次后标记为健康。
配置完成后,建议持续观察几天错误日志和状态页,根据实际故障频率微调max_fails、fail_timeout和interval参数,让健康检查更贴合你的业务节奏。