【发布时间】:2014-12-19 13:50:38
【问题描述】:
我们在客户端-服务器模式下使用 hazelcast。 hazelcast 集群包含 2 个 hazelcast 节点,我们有大约 25 个客户端连接到集群。
我现在正在寻找的是一个简单的检查,试图确定集群是否仍然存在。这应该是一个相当便宜的操作,因为这个检查会非常频繁地发生在每个客户端上(我可以想象每秒一次)。
最好的方法是什么?
【问题讨论】:
标签: java client-server hazelcast
我们在客户端-服务器模式下使用 hazelcast。 hazelcast 集群包含 2 个 hazelcast 节点,我们有大约 25 个客户端连接到集群。
我现在正在寻找的是一个简单的检查,试图确定集群是否仍然存在。这应该是一个相当便宜的操作,因为这个检查会非常频繁地发生在每个客户端上(我可以想象每秒一次)。
最好的方法是什么?
【问题讨论】:
标签: java client-server hazelcast
最简单的方法是将 LifecycleListener 注册到客户端 HazelcastInstance:
HazelcastInstance client = HazelcastClient.newHazelcastClient();
client.getLifecycleService().addLifecycleListener(new LifecycleListener() {
@Override
public void stateChanged(LifecycleEvent event) {
}
})
客户端使用周期性心跳来检测集群是否仍在运行。
【讨论】:
您也可以使用LifecycleService.isRunning() 方法:
HazelcastInstance hzInstance = HazelcastClient.newHazelcastClient();
hzInstance.getLifecycleService().isRunning()
【讨论】:
Unable to get alive cluster connection)返回true。
作为isRunning() may be true even if cluster is down,我会采用以下方法(@konstantin-zyubin's answer 和this 的混合)。这不需要事件监听器,这在我的设置中是一个优势:
if (!hazelcastInstance.getLifecycleService().isRunning()) {
return Health.down().build();
}
int parameterCount;
LocalTopicStats topicStats;
try {
parameterCount = hazelcastInstance.getMap("parameters").size();
topicStats = hazelcastInstance.getTopic("myTopic").getLocalTopicStats();
} catch (Exception e) {
// instance may run but cluster is down:
Health.Builder builder = Health.down();
builder.withDetail("Error", e.getMessage());
return builder.build();
}
Health.Builder builder = Health.up();
builder.withDetail("parameterCount", parameterCount);
builder.withDetail("receivedMsgs", topicStats.getReceiveOperationCount());
builder.withDetail("publishedMsgs", topicStats.getPublishOperationCount());
return builder.build();
【讨论】:
我找到了一种更可靠的方法来检查 hazelcast 的可用性,因为
client.getLifecycleService().isRunning()
如前所述,当您使用异步重新连接模式时,始终返回 true。
@Slf4j
public class DistributedCacheServiceImpl implements DistributedCacheService {
private HazelcastInstance client;
@Autowired
protected ConfigLoader<ServersConfig> serversConfigLoader;
@PostConstruct
private void initHazelcastClient() {
ClientConfig config = new ClientConfig();
if (isCacheEnabled()) {
ServersConfig.Hazelсast hazelcastConfig = getWidgetCacheSettings().getHazelcast();
config.getGroupConfig().setName(hazelcastConfig.getName());
config.getGroupConfig().setPassword(hazelcastConfig.getPassword());
for (String address : hazelcastConfig.getAddresses()) {
config.getNetworkConfig().addAddress(address);
}
config.getConnectionStrategyConfig()
.setAsyncStart(true)
.setReconnectMode(ClientConnectionStrategyConfig.ReconnectMode.ASYNC);
config.getNetworkConfig()
.setConnectionAttemptLimit(0) // infinite (Integer.MAX_VALUE) attempts to reconnect
.setConnectionTimeout(5000);
client = HazelcastClient.newHazelcastClient(config);
}
}
@Override
public boolean isCacheEnabled() {
ServersConfig.WidgetCache widgetCache = getWidgetCacheSettings();
return widgetCache != null && widgetCache.getEnabled();
}
@Override
public boolean isCacheAlive() {
boolean aliveResult = false;
if (isCacheEnabled() && client != null) {
try {
IMap<Object, Object> defaultMap = client.getMap("default");
if (defaultMap != null) {
defaultMap.size(); // will throw Hazelcast exception if cluster is down
aliveResult = true;
}
} catch (Exception e) {
log.error("Connection to hazelcast cluster is lost. Reason : {}", e.getMessage());
}
}
return aliveResult;
}
}
【讨论】: