Keepalived默认不检测Nginx真实服务能力,需配置vrrp_script脚本(如curl健康检查)并结合权重调整触发VIP漂移;同时须优化Nginx超时、重试及内核ARP等参数确保切换可靠生效。

Nginx 单点故障无法自动规避,必须靠 Keepalived 绑定 VIP 并做主备切换;但 Keepalived 本身不检测后端服务健康状态,这点极易被忽略。
Keepalived 怎么判断 Nginx 挂了?
Keepalived 默认只检测本机网络连通性和进程是否存在,nginx 进程活着但配置错误、worker 全卡死、或监听端口被占用时,Keepalived 仍认为“正常”,VIP 不会漂移。
- 必须手动添加
vrrp_script块,用killall -0 nginx或curl -f http://127.0.0.1/health检查真实服务能力 - 脚本返回非 0 状态时,Keepalived 才会触发权重下降或强制切换
-
interval建议设为 2 秒以内,fall和rise至少为 2,避免抖动误切 - 不要依赖
ps aux | grep nginx—— 容易匹配到 grep 自身进程导致误判
Nginx 配置里哪些项影响 Keepalived 切换可靠性?
Keepalived 的 VIP 漂移依赖于 Nginx 是否真正响应请求,而 Nginx 的行为受以下配置直接影响:
-
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;必须显式开启,否则后端挂掉时 Nginx 会直接返回 502 而不尝试重试,客户端感知明显 -
proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout应小于 Keepalived 的interval × fall,否则健康检查超时滞后于实际故障 - 禁用
keepalive_timeout 0;—— 长连接可能掩盖后端失联,建议设为 15~30 秒 - 不要在
upstream中用ip_hash且未配down标记:某台后端宕机后,对应 IP 的请求会持续失败,但 Nginx 不会主动剔除它
为什么 VIP 漂移后客户端访问仍中断?
常见原因不是 Keepalived 配置错,而是网络层或内核参数没调好:
- 两台 Nginx 服务器必须在同一二层网络(同 VLAN / 同交换机),VRRP 依赖组播
224.0.0.18,跨路由需额外配置 IGMP 或改用单播 - 防火墙常拦截 VRRP 包:
iptables -I INPUT -d 224.0.0.18 -j ACCEPT和-p vrrp规则缺一不可 - Linux 内核需开启
net.ipv4.ip_forward = 0(默认即可),但若启用了rp_filter(反向路径过滤),会导致 VIP 响应包被丢弃:sysctl -w net.ipv4.conf.all.rp_filter=0 - ARP 缓存未刷新:客户端或网关缓存了旧的 MAC 地址,可加
notify_master脚本执行arping -U -I eth0 192.168.1.100强制通告
如何验证高可用是否真生效?
不能只看 ip a 显示 VIP 在哪台机器上,要模拟真实故障链路:
- 在 MASTER 上执行
kill -STOP $(cat /usr/local/nginx/logs/nginx.pid)(暂停进程,而非杀死),观察 BACKUP 是否在advert_int × (fall + 1)秒内接管 VIP - 用另一台机器持续
curl -sI http://VIP/health | head -1,确认 HTTP 状态码在切换过程中最多丢失 1~2 次请求 - 抓包验证:在客户端侧用
tcpdump -i any host VIP and port 80,确认 TCP SYN 始终能到达当前 MASTER 的物理 IP,且无重传激增 - 注意日志时间戳对齐:
tail -f /var/log/messages(Keepalived)和tail -f /usr/local/nginx/logs/access.log要同步查看,避免误判“切换延迟”
最常被跳过的一步是:没在 notify_master/notify_backup 脚本里加服务启停逻辑。比如 VIP 漂到 BACKUP 后,Nginx 可能因配置未加载或 worker 数不足而无法立即承接流量——这些必须由脚本显式处理,Keepalived 不会替你管 Nginx 的运行态。











