
本文详解 hazelcast 在多微服务(grpc server/client)场景下无法组网的典型问题,聚焦 tcp-ip 发现机制配置错误,并提供 yaml 与 java config 双方案的正确实践。
本文详解 hazelcast 在多微服务(grpc server/client)场景下无法组网的典型问题,聚焦 tcp-ip 发现机制配置错误,并提供 yaml 与 java config 双方案的正确实践。
Hazelcast 集群无法形成的根本原因在于 节点发现配置不一致且逻辑矛盾。从日志可见,Server 节点(127.0.0.1:9701)主动尝试连接 127.0.0.1:9702,但连接被拒绝(Connection refused),说明 Client 端并未在 9702 端口成功启动 Hazelcast 实例——这通常源于 YAML 配置缺失关键项或语义误解。
? 问题根源分析
-
Server 端配置缺陷:
hazelcast: network: join: tcp-ip: member-list: - 127.0.0.1:9701 # ✅ 自身地址不应列入 member-list - 127.0.0.1:9702 # ❌ Client 地址未确保已启动member-list 应仅包含其他待加入集群的成员地址,而非自身。将 9701 加入列表会导致 Hazelcast 尝试与自己建立冗余连接,且掩盖了 Client 未就绪的问题。
-
Client 端配置致命缺失:
hazelcast: network: public-address: 127.0.0.1:9702 # 仅声明对外地址,未指定监听端口! port: 9702 # ❌ 缺少 port 配置块,实际未绑定 9702public-address 仅用于向集群宣告本节点可被访问的地址(如 Docker 网络中需暴露宿主机 IP),不控制监听端口。必须通过 port.port 显式指定监听端口,否则 Hazelcast 使用默认端口(5701),导致 Server 无法连接到预期的 9702。
TCP-IP 发现机制依赖双向可达性:
Server 需能连接 Client 的监听端口,Client 同样需能连接 Server 的监听端口。若 Client 未正确监听 9702,则 Server 的连接请求必然失败。
✅ 正确配置方案(推荐 Java Config)
YAML 配置易因层级嵌套和默认值隐含行为引发歧义,而 Java Config 提供编译期校验与逻辑显式化。以下是修复后的完整配置:
@Configuration
public class HazelcastConfiguration {
@Bean
public Config hazelcastConfig() {
NetworkConfig networkConfig = new NetworkConfig();
// 禁用 Multicast(生产环境必备)
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
// 配置 TCP-IP 发现:仅列出其他成员地址(不含自身)
TcpIpConfig tcpIpConfig = new TcpIpConfig();
tcpIpConfig.setEnabled(true);
tcpIpConfig.addMember("127.0.0.1:9701"); // 指向 Server 的实际监听地址
networkConfig.getJoin().setTcpIpConfig(tcpIpConfig);
// 关键:显式设置本节点监听端口(Client 必须为 9702)
networkConfig.setPort(9702);
networkConfig.setPortCount(1); // 避免端口自增冲突
// 设置集群名(两端必须严格一致)
Config config = new Config()
.setClusterName("banks_data")
.setNetworkConfig(networkConfig);
// 可选:添加 Map 配置增强缓存能力
config.addMapConfig(new MapConfig()
.setName("banks-data-cache")
.setBackupCount(1)
.setMaxIdleSeconds(300)
.setEvictionConfig(new EvictionConfig()
.setEvictionPolicy(EvictionPolicy.LRU)
.setSize(10000))
);
return config;
}
}
? 关键注意事项
- 端口一致性:Server 与 Client 的 hazelcast.network.port.port 值必须唯一且互不冲突(如 9701 和 9702),且 member-list 中的地址必须精确匹配对方监听的 host:port。
- 启动顺序无关性:TCP-IP 发现支持异步重试,无需严格规定启动顺序,但需确保所有节点最终监听端口已就绪。
- Docker/K8s 环境适配:若部署在容器中,public-address 应设为容器可被外部访问的 IP+端口(如 host.docker.internal:9701),并确保宿主机防火墙放行对应端口。
- 日志验证要点:成功组网后,日志应出现类似 Members {size:2, ver:2} [ Member [127.0.0.1]:9701, Member [127.0.0.1]:9702 ] 的输出。
通过以上配置修正,Hazelcast 即可稳定构建双节点集群,为 gRPC 微服务提供高可用、低延迟的分布式缓存能力。











