Azure中CentOS虚拟机JBoss/Keycloak HA集群组网失败求助
问题背景
你在Azure环境中部署两台CentOS虚拟机运行Keycloak Standalone HA模式,使用AZURE_PING做集群发现,但节点无法互相加入,出现以下错误:
Slave WARN [org.jgroups.protocols.pbcast.GMS] (ServerService Thread Pool -- 50) ew-sit-idm-app01dc: JOIN(ew-sit-idm-app01dc) sent to ew-sit-idm-app02 timed out (after 3000 ms), on try 1
Master WARN [org.jboss.as.clustering.jgroups.protocol.UDP] (TransferQueueBundler,ejb,ew-sit-idm-app02) JGRP000032: ew-sit-idm-app02: no physical address for 1f285ecd-2f08-9b5f-6897-69ee5d871d78, dropping message
结合你的JGroups UDP栈配置,我整理了几个关键排查点和解决方案:
1. 先确认AZURE_PING的核心配置正确性
AZURE_PING是集群发现的关键,首先要确保它能正常和Azure存储交互:
- 清理配置中的多余空格:你的XML配置里
<property name="ip_mcast"> false </property>和存储账户相关的property值前后有空格,XML解析时可能会把这些空格当作值的一部分,导致配置失效。建议改成:<property name="ip_mcast">false</property> <property name="storage_account_name">{storage}</property> <property name="storage_access_key">{access}</property> - 验证存储账户权限与容器存在性:
- 确认
keycloak-ping容器已在指定存储账户中创建 - 检查使用的存储访问密钥是否拥有Blob数据读写权限,或者如果用虚拟机托管身份,要确保身份被赋予了
Storage Blob Data Contributor角色 - 可以手动尝试用存储密钥访问容器,比如用Azure CLI:
az storage blob list --account-name {storage} --account-key {access} --container-name keycloak-ping,看是否能正常返回内容
- 确认
- 检查JGroups Azure模块是否加载:Keycloak的JBAS发行版默认应该包含
jgroups-azure模块,但如果是自定义安装,可能需要确认模块是否存在于modules/system/layers/base/org/jgroups/azure目录下,启动时是否没有报错模块缺失。
2. 修正UDP传输的地址绑定问题
错误中的“no physical address”说明节点发现对方后无法获取到有效的通信地址,大概率是绑定地址配置有误:
- 指定私有IP绑定:Azure虚拟机的私有IP是集群内部通信的正确地址,建议在
standalone-ha.xml中明确绑定到私有IP:
首先定义私有接口:
然后修改JGroups的socket绑定:<interfaces> <interface name="private"> <inet-address value="${jboss.bind.address.private:10.0.0.X}"/> <!-- 替换为你的虚拟机私有IP --> </interface> </interfaces>
或者启动时通过参数指定:<socket-binding name="jgroups-udp" port="55200" interface="private"/> <socket-binding name="jgroups-udp-fd" port="54200" interface="private"/>./standalone.sh -c standalone-ha.xml -Djboss.bind.address.private=10.0.0.X - 验证UDP/TCP端口连通性:
用nc测试UDP连通性:nc -u <对方私有IP> 55200,在一端输入内容,看另一端是否能接收
用telnet测试FD_SOCK的TCP端口:telnet <对方私有IP> 54200,确认能正常连接(虽然你说端口全开,但Azure NSG和CentOS本地防火墙可能有隐藏限制,建议临时关闭firewalld测试:systemctl stop firewalld)
3. 调整JGroups集群参数优化连接
- 延长JOIN超时时间:默认3000ms在Azure网络中可能不够,修改GMS的超时配置:
<protocol type="pbcast.GMS"> <property name="join_timeout">10000</property> <!-- 调整为10秒 --> <property name="print_local_addr">true</property> <!-- 开启本地地址打印,方便排查 --> </protocol> - 确认单播配置正确性:因为你关闭了组播(
ip_mcast=false),要确保UNICAST3协议没有被遗漏,你的配置里已经包含,这点没问题,但可以添加单播超时参数:<protocol type="UNICAST3"> <property name="timeout">6000</property> </protocol>
4. 验证AZURE_PING的工作状态
登录Azure存储账户,查看keycloak-ping容器里是否生成了以节点名称命名的文件(比如ew-sit-idm-app01dc),文件内容应该包含节点的IP和端口信息。如果没有生成,说明AZURE_PING没有正常写入存储,回到第一步检查配置和权限;如果有文件但内容里的IP不是私有IP,说明节点绑定地址错误,回到第二步修正。
按照这个顺序排查,应该能定位到问题所在。
内容的提问来源于stack exchange,提问作者Mark Swabinski

