使用两台主机,部署了双节点高可用集群,启动正常,客户端注册和消费正常,web页面访问正常,但是集群高可用有点问题
1、使用集群查询命令发现节点并没有注册成功
2、down掉某一台机器,emqx组件不可用,客户端注册、订阅都不正常了
请问下是那块儿没做对,按理来说双节点任意节点down机,应该都不影响的
使用两台主机,部署了双节点高可用集群,启动正常,客户端注册和消费正常,web页面访问正常,但是集群高可用有点问题
1、使用集群查询命令发现节点并没有注册成功
2、down掉某一台机器,emqx组件不可用,客户端注册、订阅都不正常了
请问下是那块儿没做对,按理来说双节点任意节点down机,应该都不影响的
图看出来,集群已经加入成功:两个 Dashboard 都能看到 emqx@node1.emqx.io 和 emqx@node2.emqx.io 为 Running。
第一张图是 emqx_ctl 无法连接本机 Erlang 节点,而且容器状态已经是 unhealthy;
这和客户端故障转移是两个问题。
先在两台宿主机分别执行下面这些命令,把输出贴出来:
docker exec emqx sh -c 'hostname -f; env | grep -E "EMQX_(NAME|HOST|NODE__NAME|NODE__COOKIE)|WITH_EPMD"; emqx_ctl status; emqx_ctl cluster status'
docker inspect --format '{{json .State.Health}}' emqx
docker logs --tail 200 emqx
重点检查:
node.cookie 必须完全一致;node1.emqx.io、node2.emqx.io 在两个容器内都要解析到对端地址;4370、5370 要双向可达;只有启用了 WITH_EPMD=1 才额外检查 4369 和 node.dist_listen_min/max。ping 通只说明 ICMP 正常,不能证明 Erlang/RPC 端口可用。另外,还要说明一下的是:EMQX 集群不会把已经建立在故障节点上的 TCP 连接无缝搬到另一节点。节点宕机后,这些连接一定会断,客户端必须自动重连,并通过 TCP 负载均衡/VIP 连接到仍健康的节点;如果客户端一直直连某一台机器的 IP,那台机器停掉后自然就无法注册和订阅。可以先确认客户端接入地址是不是单节点 IP,以及前面有没有带健康检查的 LB。
现在可以定位了:unhealthy 的直接原因是容器节点名配置不一致,不是 Dashboard 里的集群没有加入。
截图里 hostname -f 返回容器 ID 3f32...,但 EMQX_HOST=node1.emqx.io;健康检查同时报 Node emqx@node1.emqx.io not responding to pings。EMQX 容器的健康检查就是执行 emqx_ctl status,节点名在容器内不能正确解析时就会出现这个结果。
先备份两台机器挂载的 /opt/emqx/data 和配置,再把每台容器的 hostname 与 EMQX_HOST 对齐。例如 node1:
hostname: node1.emqx.io
environment:
EMQX_HOST: node1.emqx.io
EMQX_NODE__COOKIE: "同一个非默认值"
node2 对应改成 node2.emqx.io。还要保证两个容器内都能把这两个名字解析到对端实际可达的地址;用 Docker network alias、DNS 或 extra_hosts 都可以。不要直接清空 data,EMQX 4.4 的数据目录包含节点名,改节点名之前必须备份。
重建后两边都验证:
docker exec emqx sh -c 'hostname -f; getent hosts node1.emqx.io node2.emqx.io; emqx_ctl status; emqx_ctl cluster status'
NGINX 这层也要补故障摘除。开源版 NGINX stream 没有主动 MQTT 健康检查,max_fails/fail_timeout 只是连接失败后的被动摘除,可以先显式配置:
upstream mqtt_servers {
server 192.168.112.92:1883 max_fails=1 fail_timeout=10s;
server 192.168.112.93:1883 max_fails=1 fail_timeout=10s;
}
server {
listen 1883;
proxy_pass mqtt_servers;
proxy_connect_timeout 3s;
proxy_next_upstream on;
proxy_next_upstream_tries 2;
}
先执行 nginx -t,确认当前 NGINX 版本支持这些指令再 reload。节点宕机时,原来落在该节点上的 MQTT TCP 连接仍会断,客户端必须重连;被动摘除只能保证后续连接尽快落到另一节点。最后确认 VIP 后面确实有两台 NGINX,否则单台 NGINX 仍然是单点。
好的,谢谢,感谢支持,祝好