2016-03-04 71 views
2

使用Akka 2.3.14,我試圖創建各種服務的Akka集羣。到目前爲止,我已經將所有「服務」放在了一個集羣跨多個節點的工件中,但現在我試圖將這個工件分解成多個服務,這些服務都存在於同一個集羣中。可以Akka羣集客戶端發送消息到羣集節點不在初始聯繫人?

因此,在打破這種情況下,我們設計了它,以便羣集上的任何節點都將首先嚐試連接到種子節點。如果沒有種子節點,它將查看它是否是作爲種子節點運行的候選(如果它位於種子節點可以在的同一主機上),在這種情況下,它將抓取開放的種子節點端口併成爲種子節點。所以從這個意義上說,集羣中的任何服務都可以成爲種子節點。

至少,這是主意。我們作爲單獨服務運行的這個系統的API實現了一個ClusterClient進入這個系統。 initialContacts設置爲與種子節點相同。問題是我可以通過ClusterClient發送消息的唯一接待演員是種子節點上的角色。

這是一個例子,如果它有幫助。比方說,我有一個字符串服務和一個雙重服務,每個服務的接待員分別是一個StringActor和一個DoubleActor。現在可以說我有它發送StringMessages和DoubleMessages到StringActor和DoubleActor

所以爲了簡單起見,客戶服務,讓我們說我有兩個節點,Server1和Server2上則:

seed-nodes = ["akka.tcp://[email protected]:2773", "akka.tcp://[email protected]:2773"] 

我ClusterClient將被初始化像這樣:

system.actorOf(
    ClusterClient.props(
     Set(
      system.actorSelection("akka.tcp://[email protected]:2773/user/receptionist"), 
      system.actorSelection("akka.tcp://[email protected]:2773/user/receptionist") 
     ) 
    ),  
    "clusterClient" 
) 

這裏是正在發生的對我的情況:

  1. 如果StringServices首先在兩臺服務器上啓動,則客戶端服務中的DoubleMessages會消失在以太網中。
  2. 如果DoubleServices首先在兩臺服務器上啓動,則來自客戶端服務的StringMessages會消失在以太網中。
  3. 如果StringService首先在serverX上啓動,DoubleService首先在serverY上啓動,那麼所有的StringMessages都會被髮送到serverX,所有的DoubleMessages都會被髮送到serverY,這並不像上面那樣糟糕,但它意味着它不是真正的縮放。

這不是我所期望的,這可能只是我的代碼中的缺陷,所以我想知道這是否是預期的行爲。如果沒有,那麼是否有另一種Akka概念可以幫助我呢?

可以說,我可以讓一個服務類型成爲我的入口點,就像可以接受StringMessages或DoubleMessages的RoutingService,然後將其發送到正確的服務。但是,如果客戶端服務只能將消息發送到初始聯繫人中的RoutingService實例,則無法動態擴展RoutingService,因爲無論添加客戶端服務的節點數量多少,都只能發送給初始聯繫人。

我也在考慮在客戶端服務中訂閱ClusterEvents並查看是否可以在羣集中添加和刪除羣集客戶端的初始聯繫人,但是我不確定這是否可行,感覺應該有更好的解決方案。

回答

4

這是我發現在更多故障排除,在情況下,它可以幫助別人:

的ClusterClient將嘗試連接到初始接觸的順序,然後只發送它通過該連接的消息。如果您要在每個節點上部署不同的服務,您將遇到問題,因爲從ClusterClient發送的消息只會發送到與其連接的節點。通過這種方式,您可以將ClusterClient視爲合法的客戶端,它將連接到您提供的URL,然後通過該URL繼續與服務器進行通信。

通過閱讀Distributed Workers示例,我意識到我的前端或本例中的路由服務實際上應該是羣集的一部分,而不是充當客戶端。爲此,我使用了DistributedPubSub方法。

+0

如果您與工作人員訂閱調解員,並且您的初始聯繫人是包含pub/sub調解員的主管,那麼您肯定可以連接到羣集中的不同節點。您的IPOC在這一點上更像種子節點。 –