Akka提供的很是吸引人的特性之一就是輕鬆構建自定義集羣,這也是我要選擇Akka的最基本緣由之一。若是你不想敲太多代碼,也能夠經過簡單的配置構建一個很是簡單的集羣。本文爲說明Akka集羣構建的學習成本低廉,以Akka官網的例子代碼出發,進行簡單改造後與Spring集成,有關Spring集成的信息你能夠選擇閱讀《Spring與Akka的集成》一文。本文所講述的是一款十分簡便的集羣監聽器,它經過訂閱集羣成員的消息,對整個集羣的成員進行管理(管理的方式只是打印一行日誌)。html
根據Akka官網的描述——Akka集羣特性提供了容錯的、去中心化的、基於集羣成員關係點對點的,不存在單點問題、單點瓶頸的服務。其實現原理爲閒聊協議和失敗檢查。java
這裏以Akka官網提供的成員狀態狀態圖爲例,如圖1所示。node
圖1spring
圖1展現了狀態轉換的兩個因素:動做和狀態。bash
本節將要展現構建集羣所須要的最基本的配置,幾乎不會引入過多的開發成本,一個集羣就構建完成了。application.conf文件的內容以下:架構
akka { actor { provider = "akka.cluster.ClusterActorRefProvider" } remote { log-remote-lifecycle-events = off netty.tcp { hostname = "127.0.0.1" port = 2551 } } cluster { seed-nodes = [ "akka.tcp://metadataAkkaSystem@127.0.0.1:2551", "akka.tcp://metadataAkkaSystem@127.0.0.1:2552"] #//#snippet # excluded from snippet auto-down-unreachable-after = 10s #//#snippet # auto downing is NOT safe for production deployments. # you may want to use it during development, read more about it in the docs. # # auto-down-unreachable-after = 10s # Disable legacy metrics in akka-cluster. metrics.enabled=off } }
此配置文件與我在《使用Akka的遠程調用》一文中的配置有不少不一樣:app
咱們建立一個簡單的集羣監聽器SimpleClusterListener(其實是一個Actor,由於繼承了UntypedActor),它向集羣訂閱MemberEvent(成員事件)和UnreachableMember(不可達成員)兩種消息,來對集羣成員進行管理(打印),其實現見代碼清單1所示。tcp
代碼清單1ide
@Named("SimpleClusterListener") @Scope("prototype") public class SimpleClusterListener extends UntypedActor { LoggingAdapter log = Logging.getLogger(getContext().system(), this); Cluster cluster = Cluster.get(getContext().system()); // subscribe to cluster changes @Override public void preStart() { // #subscribe cluster.subscribe(getSelf(), ClusterEvent.initialStateAsEvents(), MemberEvent.class, UnreachableMember.class); // #subscribe } // re-subscribe when restart @Override public void postStop() { cluster.unsubscribe(getSelf()); } @Override public void onReceive(Object message) { if (message instanceof MemberUp) { MemberUp mUp = (MemberUp) message; log.info("Member is Up: {}", mUp.member()); } else if (message instanceof UnreachableMember) { UnreachableMember mUnreachable = (UnreachableMember) message; log.info("Member detected as unreachable: {}", mUnreachable.member()); } else if (message instanceof MemberRemoved) { MemberRemoved mRemoved = (MemberRemoved) message; log.info("Member is Removed: {}", mRemoved.member()); } else if (message instanceof MemberEvent) { // ignore } else { unhandled(message); } } }
logger.info("Start simpleClusterListener"); final ActorRef simpleClusterListener = actorSystem.actorOf(springExt.props("SimpleClusterListener"), "simpleClusterListener"); actorMap.put("simpleClusterListener", simpleClusterListener); logger.info("Started simpleClusterListener");
咱們首先啓動第一個種子節點,配置跟第一小節徹底一致。咱們觀察SimpleClusterListener的日誌輸出以下圖所示。post
咱們再啓動第二個種子節點,其配置的akka.remote.netty.tcp.port爲2552,咱們觀察SimpleClusterListener的日誌輸出以下圖所示。
咱們再啓動一個非種子節點,沒有爲其指定akka.remote.netty.tcp.port,咱們觀察SimpleClusterListener的日誌輸出以下圖所示。
能夠看到新加入的節點信息被SimpleClusterListener打印出來了,細心的同窗可能發現了一些Akka集羣中各個節點的狀態遷移信息,第一個種子節點正在加入自身建立的集羣時的狀態時JOINING,因爲第一個種子節點將本身率先選舉爲Leader,所以它還將本身的狀態改變爲Up。後面它還將第二個種子節點和第三個節點從JOINING轉換到Up狀態。
咱們中止第三個加入的節點,咱們觀察SimpleClusterListener的日誌輸出以下圖所示。
能夠看到其狀態首先被標記爲Down,最後被轉換爲Removed。
經過以上介紹相信你們對使用Akka構建集羣有了基本的認識,是否是很輕鬆?若是想要繼續瞭解如何使用Akka構建集羣,請閱讀《使用Akka構建集羣(二)》。