Я использую 3.8.1, я заметил некоторые проблемы, связанные с поведением клиентов при повторном подключении после того, как участники отскакивают. Несмотря на установку попыток повторного подключения, клиенты часто отключаются после регистрации повторяющихся предупреждений о невозможности получить подключение к кластеру - и это несмотря на то, что всегда есть хотя бы один выживший член.
Так почему же происходит отключение? Я считаю, что если есть хотя бы один живой участник, ни один клиент никогда не должен отключаться. И почему клиент неоднократно регистрируется и предупреждает после того, как участник отказался?
Тест: ко мне присоединились 2 участника. У меня есть 3 клиента, которые подключаются к обоим участникам через TCP. Клиенты настроены на повторное подключение 1000 раз. Клиент 1 зацикливается и просто помещает случайное значение в тот же ключ. Клиенты 2 и 3 слушают эту карту и регистрируют обновление.
Шаги: Запустите член 1, участник 2. Запустите оба клиента 2, 3 (слушатели). Запустите клиент 1 (писатель). На данный момент все в порядке. Никаких предупреждений в логах.
Откажитесь от члена 1, дождитесь его запуска. Участник отказов 2. Участник отказов 1.
Не всегда, но часто клиенты сообщают об этом:
Put 29: d16b0acd-d0d6-4722-b511-7fd975774f8c
May 10, 2017 11:41:10 AM com.hazelcast.client.spi.impl.ClusterListenerSupport
WARNING: hz.client_0 [dev] [3.8.1] Unable to get alive cluster connection, try in 0 ms later, attempt 4 of 1000.
May 10, 2017 11:41:10 AM com.hazelcast.client.spi.impl.ClusterListenerSupport
INFO: hz.client_0 [dev] [3.8.1] Trying to connect to [127.0.0.1]:5701 as owner member
Put 30: f91ec949-19bd-4039-95d3-28c7abd0f241
May 10, 2017 11:41:15 AM com.hazelcast.client.spi.impl.ClusterListenerSupport
INFO: hz.client_0 [dev] [3.8.1] Trying to connect to [127.0.0.1]:5702 as owner member
Put 31: 2af9fb36-d501-4b0b-9fc8-6b36d467a929
May 10, 2017 11:41:20 AM com.hazelcast.client.spi.impl.ClusterListenerSupport
INFO: hz.client_0 [dev] [3.8.1] Trying to connect to [127.0.0.1]:5701 as owner member
Put 32: f08bd6ca-a79f-44f4-9064-42e47953c37a
Клиенты все еще могут работать и прослушивать события, НО по прошествии определенного периода они часто отключаются:
May 10, 2017 11:25:04 AM com.hazelcast.core.LifecycleService
INFO: hz.client_0 [dev] [3.8.1] HazelcastClient 3.8.1 (20170411 - f1e9264) is SHUTTING_DOWN
May 10, 2017 11:25:04 AM com.hazelcast.client.connection.ClientConnectionManager
INFO: hz.client_0 [dev] [3.8.1] Removed connection to endpoint: [localhost]:5701, connection: ClientConnection{alive=false, connectionId=5, socketChannel=DefaultSocketChannelWrapper{socketChannel=java.nio.channels.SocketChannel[closed]}, remoteEndpoint=[localhost]:5701, lastReadTime=2017-05-10 11:25:04.021, lastWriteTime=2017-05-10 11:25:04.084, closedTime=2017-05-10 11:25:04.084, lastHeartbeatRequested=2017-05-10 11:25:03.834, lastHeartbeatReceived=2017-05-10 11:25:03.834, connected server version=3.8.1}
May 10, 2017 11:25:04 AM com.hazelcast.client.connection.ClientConnectionManager
INFO: hz.client_0 [dev] [3.8.1] Removed connection to endpoint: [localhost]:5702, connection: ClientConnection{alive=false, connectionId=6, socketChannel=DefaultSocketChannelWrapper{socketChannel=java.nio.channels.SocketChannel[closed]}, remoteEndpoint=[localhost]:5702, lastReadTime=2017-05-10 11:24:59.513, lastWriteTime=2017-05-10 11:25:04.084, closedTime=2017-05-10 11:25:04.084, lastHeartbeatRequested=2017-05-10 11:17:43.840, lastHeartbeatReceived=2017-05-10 11:17:43.840, connected server version=3.8.1}
May 10, 2017 11:25:04 AM com.hazelcast.core.LifecycleService
INFO: hz.client_0 [dev] [3.8.1] HazelcastClient 3.8.1 (20170411 - f1e9264) is SHUTDOWN
Отключение клиента:
INFO: hz.client_0 [dev] [3.8.1] Removed connection to endpoint: [localhost]:5701, connection: ClientConnection{alive=false, connectionId=8, socketChannel=DefaultSocketChannelWrapper{socketChannel=java.nio.channels.SocketChannel[closed]}, remoteEndpoint=[localhost]:5701, lastReadTime=2017-05-10 11:45:31.791, lastWriteTime=2017-05-10 11:45:31.791, closedTime=2017-05-10 11:45:31.791, lastHeartbeatRequested=2017-05-10 11:45:23.604, lastHeartbeatReceived=2017-05-10 11:45:23.605, connected server version=3.8.1}
May 10, 2017 11:45:31 AM com.hazelcast.core.LifecycleService
INFO: hz.client_0 [dev] [3.8.1] HazelcastClient 3.8.1 (20170411 - f1e9264) is CLIENT_DISCONNECTED
Отчеты участников:
May 10, 2017 11:47:32 AM com.hazelcast.client.impl.protocol.task.AuthenticationMessageTask
WARNING: [localhost]:5701 [dev] [3.8.1] Member having uuid 8847c2e3-2fcb-428f-a827-d0e24f5624a1 is not part of the cluster. Client Authentication rejected.
May 10, 2017 11:47:32 AM com.hazelcast.client.impl.protocol.task.AuthenticationMessageTask
WARNING: [localhost]:5701 [dev] [3.8.1] Received auth from Connection[id=222, /127.0.0.1:5701->/127.0.0.1:53883, endpoint=null, alive=true, type=NONE] with principal ClientPrincipal{uuid='f1e5d928-23b2-4fdf-bd3f-9db1778a5a8c', ownerUuid='8847c2e3-2fcb-428f-a827-d0e24f5624a1'} , authentication failed
Основной член:
public class HzNodeTest {
private HazelcastInstance service;
@Before
public void setUp() throws Exception {
Config config = new Config();
JoinConfig join = config.getNetworkConfig().setPort(5701).getJoin();
join.getMulticastConfig().setEnabled(false);
join.getAwsConfig().setEnabled(false);
join.getTcpIpConfig().addMember("localhost:5701").addMember("localhost:5702").setEnabled(true);
service = Hazelcast.newHazelcastInstance(config);
}
@After
public void tearDown() throws Exception {
service.shutdown();
}
@Test
public void testStart() throws InterruptedException {
Thread.sleep(1000000000);
}
}
Secondary member:
public class HzNodeSecondaryTest {
private HazelcastInstance service;
@Before
public void setUp() throws Exception {
Config config = new Config();
JoinConfig join = config.getNetworkConfig().setPort(5702).getJoin();
join.getMulticastConfig().setEnabled(false);
join.getAwsConfig().setEnabled(false);
join.getTcpIpConfig().addMember("localhost:5701").addMember("localhost:5702").setEnabled(true);
service = Hazelcast.newHazelcastInstance(config);
}
@After
public void tearDown() throws Exception {
service.shutdown();
}
@Test
public void testStart() throws InterruptedException {
Thread.sleep(1000000000);
}
}
Listener:
public class HzListenerTest {
private HazelcastInstance service;
private AtomicLong counter = new AtomicLong();
@Before
public void setUp() throws Exception {
ClientConfig clientConfig = new ClientConfig();
clientConfig.getNetworkConfig().addAddress("localhost:5701").addAddress("localhost:5702").setConnectionAttemptLimit(1000);
service = HazelcastClient.newHazelcastClient(clientConfig);
}
@After
public void tearDown() throws Exception {
service.shutdown();
}
@Test
public void testListen() throws InterruptedException {
service.getMap("TEST").addEntryListener(new Listener(), true);
Thread.sleep(1000000);
}
private class Listener implements EntryAddedListener, EntryUpdatedListener, EntryRemovedListener,
EntryEvictedListener {
@Override
public void entryAdded(EntryEvent event) {
System.out.println("onAdded " + counter.getAndIncrement() + ": " + event);
}
@Override
public void entryEvicted(EntryEvent event) {
System.out.println("onEvicted " + counter.getAndIncrement() + ": " + event);
}
@Override
public void entryRemoved(EntryEvent event) {
System.out.println("onRemoved " + counter.getAndIncrement() + ": " + event);
}
@Override
public void entryUpdated(EntryEvent event) {
System.out.println("onUpdated " + counter.getAndIncrement() + ": "+ event);
}
}
}
Updater:
public class HzUpdaterTest {
private HazelcastInstance service;
@Before
public void setUp() throws Exception {
ClientConfig clientConfig = new ClientConfig();
clientConfig.getNetworkConfig().addAddress("localhost:5701").addAddress("localhost:5702").setConnectionAttemptLimit(1000);
service = HazelcastClient.newHazelcastClient(clientConfig);
service.getMap("TEST").put("1", UUID.randomUUID().toString());
}
@After
public void tearDown() throws Exception {
service.shutdown();
}
@Test
public void testSpin() {
for (int i = 0; i < 10000; i++) {
try {
String value = UUID.randomUUID().toString();
service.getMap("TEST").put("1", value);
System.out.println("Put " + i + ": " + value);
Thread.sleep(5000);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
}