2015-01-12 96 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