Есть по крайней мере два подхода, которые могут быть использованы, чтобы найти число абонентов темы.
- Используйте общедоступный API и получите список кластера
Member
s.
- Используйте SPI Hazelcast и предоставите
ManagedService
, у которого есть доступ к внутреннему Hazelcast.
Оба эти подхода работают нормально, но последний включает в себя больше кодирования и хорошее знание SPI, которое не так широко используется.
Подход 1: Найти кластер Member
s Чтобы найти все элементы, которые являются (в настоящее время) часть кластера вы можете использовать следующий код:
final Set<Member> members = hazelcastInstance.getCluster().getMembers();
Вышеприведенные возвращает Set
из Member
объекты, которые подробно описаны here.
При запуске Member
в кластере вы можете установить пользовательские свойства. Это позволяет вам добавить свою собственную логику для запуска Member
.
Следующий тест показывает, как это можно использовать:
public class TopicCounterTest {
// Setup a hazelcast instance, bind the topic name as a custom property
public HazelcastInstance setupHazelcastInstance(final String topicName) {
// Set the custom property (in this case a boolean bound to the topic name)
final MemberAttributeConfig topicMemberConfig = new MemberAttributeConfig();
topicMemberConfig.setBooleanAttribute(topicName, true);
final Config config = new Config();
config.setMemberAttributeConfig(topicMemberConfig);
config.setProperty("hazelcast.initial.min.cluster.size", "1");
// Create a HazelcastInstance
return Hazelcast.newHazelcastInstance(config);
}
// Use a Java 8 stream to count all "Member"s that have the
// custom property set
public long numberOfTopicListeners(
final HazelcastInstance hazelcastInstance,
final String topicName) {
return hazelcastInstance.getCluster().getMembers().stream()
.map(member -> {
final Map<String, Object> attributes = member.getAttributes();
return Optional.ofNullable(
member.getBooleanAttribute(topicName))
.orElse(false);
})
.count();
}
// Test case, start two instances and verify that they both are listeners on the topic
@Test
public void testTopicCounter() {
final HazelcastInstance h1 = setupHazelcastInstance("testTopic");
final HazelcastInstance h2 = setupHazelcastInstance("testTopic");
Assert.assertEquals(2l, numberOfTopicListeners(h1, "testTopic"));
Assert.assertEquals(2l, numberOfTopicListeners(h2, "testTopic"));
}
}
подход 2: Используйте Hazelcast SPI и предоставить пользовательские ManagedService
Другой подход требует использования Hazelcast SPI (Интерфейс поставщика услуг). Для этого требуется больше кода, чем первый подход, и, кроме всего прочего, вы должны предоставить ManagedService
, зарегистрируйте эту услугу, а затем получите NodeEngine
через обратный вызов. NodeEngine
имеет дескриптор EventService
, который затем можно использовать для вызова метода getRegistrations
.
Одна из проблем с подходом SPI заключается в том, что для этого требуется дополнительный код SPI, и вам необходимо найти способ обмена данными между управляемым сервисом и вашим приложением. Как работать с SPI описывается на Hazelcast website.
Рекомендация
Моя рекомендация состоит в том, чтобы использовать первый подход. Используйте общедоступный API: s и просто зарегистрируйте настраиваемое свойство, которое вы можете использовать, чтобы основывать свою логику. Простой, быстрый и безопасный.
Эта информация доступна для общественности. Также темы построены на внутренней системе событий, которая используется совместно с вечерней системой обновления коллекции и рядом с кешем. На этом уровне мы больше не видим, что это за слушатель. – pveentjer
не уверен, что я понял, что вы сказали ... – tbo