2015-01-12 98 views
1

我想问一下,是否有可能通过Hazelcast获得订阅全集群主题的总数以及如何?总订阅了hazelcast主题

例如

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

long totalSubscribed = topic.getSubscribed() 

谢谢

+0

此信息对公众有效。此外,这些主题建立在与收藏更新夜晚系统和接近缓存共享的内部事件系统上。在那个层面上,我们不再看到它是什么样的听众。 – pveentjer

+0

不知道我的理解是什么你说的... – tbo

回答

0

有一些可以用来寻找话题的用户数量至少两种方法。

  1. 使用公共API并获取集群的列表Member s。
  2. 使用Hazelcast SPI,并提供可访问Hazelcast内部的ManagedService

这两种方法都可以正常工作,但后者涉及更多的编码和对SPI不熟悉的SPI知识。

方法1:查找集群Member小号 要查找所有的成员都可以使用下面的代码群集的(目前)部分:

final Set<Member> members = hazelcastInstance.getCluster().getMembers(); 

以上的回报Member一个Set完全描述的物体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")); 
    } 
} 

方法二:使用Hazelcast SPI和提供自定义ManagedService

另一种方法要求使用Hazelcast SPI(服务提供商接口)。它需要比第一种方法更多的代码,除此之外,您必须提供ManagedService,注册该服务,然后通过回调获得NodeEngineNodeEngine具有EventService的句柄,您可以使用该句柄来调用方法getRegistrations

SPI方法的一个问题是它需要SPI更多的代码,并且您需要找到一种方法来在托管服务和应用程序之间共享数据。在Hazelcast website上描述了如何使用SPI。

建议

我的建议是使用第一种方法。利用公共API:s并简单地注册一个自定义属性,您可以使用它来基于您的逻辑。简单,快速和安全。

+0

谢谢你的回答,因为不是所有的成员都会订阅我的话题我终于最终在hazelcast中使用原子龙来保存订户 – tbo

+0

@tbo这几乎就是什么我试图解释!如果不是所有*成员都订阅该主题,则需要某种属性来区分它们(如上面的“I_LISTEN_TO_FOO_TOPIC”)。但是,如果* all *成员确实倾听了该主题,则可以简单地计算成员。我认为atomiclong方法存在的一个问题是,如果其中一个成员脱离集群,计数器将不会丢失(但是集群方法会处理该问题)。 – 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