健康检查脚本必须在100ms内干净退出,否则高频触发会导致CPU飙升;应改用轻量命令(如curl -m1、bash TCP重定向、kill -0)、提高interval至2–3秒、加flock锁防并发,并通过pidstat和日志验证优化效果。

关注健康检查脚本的执行频率与阻塞行为
Keepalived 在主备切换前后会高频触发健康检查(尤其是 notify_master/notify_backup 或 vrrp_script 中定义的脚本),若脚本本身耗时长、未设超时或存在同步阻塞(如 curl 等待响应无 timeout、数据库连接未设 connect_timeout),会导致子进程堆积,短时间内大量 fork + exec,显著拉升 CPU 使用率。重点不是“脚本功能是否正确”,而是“它是否在 100ms 内干净退出”。
用轻量替代方案重写关键检查逻辑
避免在 vrrp_script 中直接调用 heavy 工具(如 python 脚本含 requests、psql 全量查表、netstat 遍历所有端口)。推荐做法:
- HTTP 健康检查改用 curl -s -f -m 1 -o /dev/null http://127.0.0.1:8080/health(-m 1 强制 1 秒超时,-f 忽略 HTTP 错误码但不阻塞)
- TCP 端口检查用 timeout 0.5 bash -c 'echo > /dev/tcp/127.0.0.1/6379' 2>/dev/null(原生 bash TCP 重定向,比 nc 更轻)
- 本地服务状态优先读取 pidfile + kill -0 $PID(无系统调用开销),而非 ps aux | grep
限制脚本并发与执行节奏
Keepalived 默认对每个 vrrp_script 每次检查都新建进程,若 interval 设为 1s 且脚本偶发卡顿,极易形成雪崩。建议:
- 在 keepalived.conf 中将 script 的 interval 提高到 2–3 秒(多数服务故障检测无需 sub-second 精度)
- 在脚本开头加入简单文件锁机制(如 flock -n /tmp/keepalived_check.lock),防止前一次未退出时重复启动
- 禁用不必要的 check 类型:如已用 TCP 检查 Redis 端口,就不必再跑 redis-cli ping
监控与验证优化效果
优化后需验证是否真正降低 CPU 峰值,而非掩盖问题:
- 用 pidstat -u -p $(pgrep keepalived) 1 观察主进程及子进程 CPU 占用分布
- 在 /var/log/messages 或 journalctl -u keepalived 中搜索 “vrrp_script” 执行耗时(Keepalived 2.0+ 默认记录 script exit code 和 duration)
- 模拟切换:手动 systemctl stop keepalived on backup 节点,观察 master 节点 CPU spike 是否从 40%+ 降至 5% 以内且持续时间










