同一台机器上的多个 Hazelcast 实例?

Multiple Hazelcast instances on same machine?

我正在尝试为我的 Hazelcast 集群编写单元测试 - 根据这个文档 https://hazelcast.zendesk.com/hc/en-us/articles/115004425243-How-do-I-test-my-Hazelcast-cluster-

我的代码是这样写的 -

public void test(){
    HazelcastInstance instance = Hazelcast.newHazelcastInstance(); 
    HazelcastInstance instance2 = Hazelcast.newHazelcastInstance();                
}

我的控制台显示 -

Members [1] {
    Member [MY IP]:5701 -  this
}

Members [1] {
    Member [MY IP]:5702 - this
}

端口号变了,IP不变,但不在同一个集群。我该怎么做才能让它们成为同一集群的一部分(在单个 JVM 上)? 更新

更多控制台数据 -

Jul 31, 2018 3:21:00 PM com.hazelcast.config.XmlConfigLocator
INFO: Loading 'hazelcast-default.xml' from classpath.
Jul 31, 2018 3:21:01 PM com.hazelcast.instance.DefaultAddressPicker
INFO: [LOCAL] [dev] [3.7.4] Prefer IPv4 stack is true.
Jul 31, 2018 3:21:01 PM com.hazelcast.instance.DefaultAddressPicker
INFO: [LOCAL] [dev] [3.7.4] Picked [MY_IP]:5701, using socket     ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5701], bind any local is true
Jul 31, 2018 3:21:01 PM com.hazelcast.system
INFO: [MY_IP]:5701 [dev] [3.7.4] Hazelcast 3.7.4 (20161209 - 3df1bb5) starting at [MY_IP]:5701
Jul 31, 2018 3:21:01 PM com.hazelcast.system
INFO: [MY_IP]:5701 [dev] [3.7.4] Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
Jul 31, 2018 3:21:01 PM com.hazelcast.system
INFO: [MY_IP]:5701 [dev] [3.7.4] Configured Hazelcast Serialization version : 1
Jul 31, 2018 3:21:01 PM com.hazelcast.spi.impl.operationservice.impl.BackpressureRegulator
INFO: [MY_IP]:5701 [dev] [3.7.4] Backpressure is disabled
Jul 31, 2018 3:21:01 PM com.hazelcast.instance.Node
INFO: [MY_IP]:5701 [dev] [3.7.4] Creating MulticastJoiner
Jul 31, 2018 3:21:01 PM com.hazelcast.core.LifecycleService
INFO: [MY_IP]:5701 [dev] [3.7.4] [MY_IP]:5701 is STARTING
Jul 31, 2018 3:21:02 PM com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl
INFO: [MY_IP]:5701 [dev] [3.7.4] Starting 4 partition threads
Jul 31, 2018 3:21:02 PM     com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl
INFO: [MY_IP]:5701 [dev] [3.7.4] Starting 3 generic threads (1 dedicated for priority tasks)
Jul 31, 2018 3:21:02 PM com.hazelcast.nio.tcp.nonblocking.NonBlockingIOThreadingModel
INFO: [MY_IP]:5701 [dev] [3.7.4] TcpIpConnectionManager configured with Non Blocking IO-                    threading model: 3 input threads and 3 output threads
Jul 31, 2018 3:21:05 PM com.hazelcast.internal.cluster.impl.MulticastJoiner
INFO: [MY_IP]:5701 [dev] [3.7.4]



Members [1] {
    Member [MY_IP]:5701 - 
this
}

Jul 31, 2018 3:21:05 PM com.hazelcast.core.LifecycleService
INFO: [MY_IP]:5701 [dev] [3.7.4] [MY_IP]:5701 is 
STARTED
Jul 31, 2018 3:21:05 PM com.hazelcast.config.XmlConfigLocator
INFO: Loading 'hazelcast-default.xml' from classpath.
Jul 31, 2018 3:21:05 PM com.hazelcast.instance.DefaultAddressPicker
INFO: [LOCAL] [dev] [3.7.4] Prefer IPv4 stack is true.
Jul 31, 2018 3:21:05 PM com.hazelcast.instance.DefaultAddressPicker
INFO: [LOCAL] [dev] [3.7.4] Picked [MY_IP]:5702, using socket 
ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5702], bind any local is 
true
Jul 31, 2018 3:21:05 PM com.hazelcast.system
INFO: [MY_IP]:5702 [dev] [3.7.4] Hazelcast 3.7.4 (20161209 - 
3df1bb5) starting at [MY_IP]:5702
Jul 31, 2018 3:21:05 PM com.hazelcast.system
INFO: [MY_IP]:5702 [dev] [3.7.4] Copyright (c) 2008-2016, 
Hazelcast, Inc. All Rights Reserved.
Jul 31, 2018 3:21:05 PM com.hazelcast.system
INFO: [MY_IP]:5702 [dev] [3.7.4] Configured Hazelcast 
Serialization version : 1
Jul 31, 2018 3:21:05 PM 
com.hazelcast.spi.impl.operationservice.impl.BackpressureRegulator
INFO: [MY_IP]:5702 [dev] [3.7.4] Backpressure is disabled
Jul 31, 2018 3:21:05 PM com.hazelcast.instance.Node
INFO: [MY_IP]:5702 [dev] [3.7.4] Creating MulticastJoiner
Jul 31, 2018 3:21:05 PM com.hazelcast.core.LifecycleService
INFO: [MY_IP]:5702 [dev] [3.7.4] [MY_IP]:5702 is                     
Jul 31, 2018 3:21:05 PM 
com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl
INFO: [MY_IP]:5702 [dev] [3.7.4] Starting 4 partition threads
Jul 31, 2018 3:21:05 PM 
com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl
INFO: [MY_IP]:5702 [dev] [3.7.4] Starting 3 generic threads (1 
dedicated for priority tasks)
Jul 31, 2018 3:21:05 PM 
com.hazelcast.nio.tcp.nonblocking.NonBlockingIOThreadingModel
INFO: [MY_IP]:5702 [dev] [3.7.4] TcpIpConnectionManager 
configured with Non Blocking IO-threading model: 3 input threads and 3 
output threads
Jul 31, 2018 3:21:08 PM 
com.hazelcast.internal.cluster.impl.MulticastJoiner
INFO: [MY_IP]:5702 [dev] [3.7.4] 


Members [1] {
    Member [MY_IP]:5702 - 
this
}

Jul 31, 2018 3:21:08 PM com.hazelcast.instance.Node
WARNING: [MY_IP]:5702 [dev] [3.7.4] Config seed port is 5701 
and cluster size is 1. Some of the ports seem occupied!
Jul 31, 2018 3:21:08 PM com.hazelcast.core.LifecycleService
INFO: [MY_IP]:5702 [dev] [3.7.4] [MY_IP]:5702 is 
STARTED

如您所述,您使用的是默认的 Hazelcast 配置,如日志中所示

INFO: Loading 'hazelcast-default.xml' from classpath.

默认的 Hazelcast 配置用于多播。这对于多台机器快速入门非常理想,对于一台机器不太好。

第一个 Hazelcast.newHazelcastInstance() 将在端口 5701 上启动一个多播组。

第二个 Hazelcast.newHazelcastInstance() 将找到正在使用的端口 5701,将占用下一个端口 5702,并在 5702 上启动多播组。

换句话说,第二个实例可以在同一个端口上,所以不能在同一个组中(因为组是基于端口的)。所以你最终得到两个不是你想要的集群。

有四个步骤可以达到你想要的效果。

  1. 您的测试类路径中需要一个 hazelcast.xml 文件。
  2. 关闭多播
  3. 开启另一个发现,TCP 在这里无疑是最简单的
  4. (可选)不要使用 3.7.4,它不是最新的,请使用 3.10.4

关闭多播不会打开 TCP。您可以选择没有发现(对某些测试有用)。

所以你需要一个看起来像这样的 hazelcast.xml:

<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.10.xsd"
       xmlns="http://www.hazelcast.com/schema/config"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <network> 
    <join>  
      <multicast enabled="false"/>
      <tcp-ip enabled="true">
        <interface>127.0.0.1</interface>
      </tcp-ip>
    </join>
  </network>
</hazelcast>

默认配置适用于单个 JVM 中的多个实例或同一台机器上的多个 JVM。

错误 Config seed port is 5701 and cluster size is 1. Some of the ports seem occupied!红鲱鱼

当您在同一台机器上启动多个实例时,它会选择不同的端口。但是,上面的错误确实表明您的实例之间存在通信问题。

当没有通信问题时,您会在日志中看到不同的输出。 启动时的辅助实例将输出类似这样的内容(注意它仍在使用 5702)。

com.hazelcast.core.LifecycleService      : [192.168.0.103]:5702 [dev] [3.11.1] [192.168.0.103]:5702 is STARTING
c.h.i.cluster.impl.MulticastJoiner       : [192.168.0.103]:5702 [dev] [3.11.1] Trying to join to discovered node: [192.168.0.103]:5701
com.hazelcast.nio.tcp.TcpIpConnector     : [192.168.0.103]:5702 [dev] [3.11.1] Connecting to /192.168.0.103:5701, timeout: 0, bind-any: true

在我的案例中,解决这个问题就像禁用本地计算机上的防火墙一样简单,因为我绑定到路由器分配的 DHCP 地址。如果您绑定到环回地址,您需要确保 OS 上的环回与多播一起正常工作。 OSX 在环回接口上使用多播时有一些已知的 Java 问题。 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=7122846

在经历了这些之后: https://docs.hazelcast.org/docs/1.9/manual/html/ch16s02.html

我得出结论,我只需要一个更好的配置来告诉 Hazelcast 将 2 个实例作为 1 个集群进行威胁。

private val hazelcastOnNode1 = newHazelcastInstance("hazelcastInstance-cluster-node1")
private val hazelcastOnNode2 = newHazelcastInstance("hazelcastInstance-cluster-node2")

@BeforeAll
fun setupTest() {
    log.info("hazelcastOnNode1: ${hazelcastOnNode1.name} is part of a cluster: ${hazelcastOnNode1.cluster}")
    log.info("hazelcastOnNode2: ${hazelcastOnNode2.name} is part of a cluster: ${hazelcastOnNode2.cluster}")
}

private fun newHazelcastInstance(instanceName: String): HazelcastInstance {
    val cfg = Config()
    cfg.instanceName = instanceName
    cfg.groupConfig.name = "hazel-cluster"
    cfg.networkConfig.join.multicastConfig.isEnabled = false
    cfg.networkConfig.join.tcpIpConfig.isEnabled = true
    cfg.networkConfig.join.tcpIpConfig.members = listOf("127.0.0.1")
    return Hazelcast.newHazelcastInstance(cfg)
}