2015-01-12 4 views
1

Я хотел спросить, можно ли получить общее количество подписчиков на тему в масштабе всей сети с помощью Hazelcast и как?Всего подписчиков на тему темы hazelcast

например.

ITopic topic = hazelcastInstance.getTopic("foo"); 

long totalSubscribed = topic.getSubscribed() 

Спасибо

+0

Эта информация доступна для общественности. Также темы построены на внутренней системе событий, которая используется совместно с вечерней системой обновления коллекции и рядом с кешем. На этом уровне мы больше не видим, что это за слушатель. – pveentjer

+0

не уверен, что я понял, что вы сказали ... – tbo

ответ

0

Есть по крайней мере два подхода, которые могут быть использованы, чтобы найти число абонентов темы.

  1. Используйте общедоступный API и получите список кластера Member s.
  2. Используйте 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 и просто зарегистрируйте настраиваемое свойство, которое вы можете использовать, чтобы основывать свою логику. Простой, быстрый и безопасный.

+0

Спасибо за ваш ответ, потому что не все участники подписываются на мою тему. Я, наконец, снова использовал атомную ленту в hazelcast, чтобы держать подписчиков. – tbo

+0

@tbo Это в значительной степени то, что Я попытался объяснить! Если не * все * участники подписываются на тему, то для их отличия требуется какой-то атрибут (как '' I_LISTEN_TO_FOO_TOPIC'' выше). Однако, если * все * участники прослушивают эту тему, вы можете просто подсчитать участников. Я полагаю, что одна из проблем с атомарным подходом заключается в том, что если один из членов выпадает из кластера, счетчик не будет падать (но кластерный подход обрабатывает это). – wassgren

0

Вы можете получить доступ к EventService (части SPI) и вызовите следующий метод:

Collection<EventRegistration> getRegistrations(String serviceName, String topic); 

Это должно дать вам представление AFAIK числа слушателей для данной темы.

+1

интересно! Как вы овладеваете «EventService»? – wassgren

+0

Либо через отражение (yuk), либо вам нужно позволить классу реализовать интерфейс ManagedService и зарегистрироваться в службе SPI. У этого есть метод 'init', который выполняет обратный вызов с NodeEngine, и там вы можете получить доступ к EventService. Проверьте приведенную ниже ссылку: https://github.com/hazelcast/hazelcast-code-samples/tree/master/spi/getting-started – pveentjer

Смежные вопросы