Keepalived 通过自定义 MQTT 健康检查脚本(如调用 mosquitto_sub 订阅 $SYS/broker/uptime)实现业务级可用性探测,并结合 VRRP VIP 漂移保障高可用;需配合 HAProxy 进行 MQTT 连接负载均衡与故障隔离。

Keepalived 本身不直接解析 MQTT 协议,但可以通过自定义健康检查脚本主动探测 EMQX、Mosquitto 等 MQTT 服务的连通性与业务可用性,再结合 VRRP 实现 VIP 自动漂移,从而保障物联网接入层的高可用。关键不在“MQTT”本身,而在如何定义“服务真正可用”。
明确监控目标:不只是端口通,更要业务可连
仅用 nc -z host port 检查 1883/8883 端口是否开放远远不够——MQTT 服务进程可能存活,但认证模块卡死、连接数超限、或 TLS 握手失败时,客户端仍无法订阅/发布。必须模拟真实 MQTT 行为:
- 使用
mosquitto_sub或mosquitto_pub(需在 Keepalived 节点安装 mosquitto-clients)发起轻量级测试连接 - 指定测试主题(如
$SYS/broker/uptime或自建keepalive/test)、设置超时(-t 2)、禁用持久化(-C)和快速退出(-W 1) - 检查返回码:0 表示连接成功且收到响应;非 0 则判定为异常
编写可落地的 vrrp_script 脚本
脚本需具备幂等性、低开销、明确退出码,并避免因临时网络抖动误判。例如保存为 /etc/keepalived/check_mqtt.sh:
#!/bin/bash
HOST="127.0.0.1"
PORT="1883"
TOPIC="\$SYS/broker/uptime"
# 尝试订阅并读取一行,1秒超时
if timeout 1 mosquitto_sub -h "$HOST" -p "$PORT" -t "$TOPIC" -C 1 -W 1 >/dev/null 2>&1; then
exit 0
else
exit 1
fi
赋予执行权限:chmod +x /etc/keepalived/check_mqtt.sh。注意:若 MQTT 服务启用了 ACL 或需要用户名密码,脚本中需补充 -u user -P pass 参数。
在 keepalived.conf 中集成检查逻辑
在 vrrp_instance 块外定义脚本,在实例内引用并绑定权重变化:
vrrp_script chk_mqtt {
script "/etc/keepalived/check_mqtt.sh"
interval 3
fall 2
rise 2
weight -30
}
vrrp_instance VI_MQTT {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication { ... }
track_script {
chk_mqtt
}
virtual_ipaddress {
192.168.206.140/24
}
}
说明:weight -30 表示当脚本连续失败 2 次(fall 2),当前节点优先级自动减 30,若低于备机优先级,则触发主备切换;恢复后连续成功 2 次(rise 2)再加回。
配合 HAProxy 做更细粒度的流量调度
Keepalived 只管 VIP 漂移,真正分发 MQTT 连接建议由 HAProxy 承担(它原生支持 PROXY protocol 和 MQTT over TCP):
- Keepalived 管理一个对外 VIP(如 192.168.206.140),绑定在 HAProxy 所在节点
- HAProxy 配置 backend 指向多个 EMQX 节点,启用
option tcp-check并自定义tcp-check send/tcp-check expect模拟 MQTT CONNECT 包 - 这样 Keepalived 保障接入入口不中断,HAProxy 保障后端集群负载均衡与单节点故障隔离











