在很多應(yīng)用場景中都會出現(xiàn)在系統(tǒng)中需要某類Actor的唯一實例(only instance)。這個實例在集群環(huán)境中可能在任何一個節(jié)點上,但保證它是唯一的。Akka的Cluster-Singleton提供對這種Singleton Actor模式的支持,能做到當(dāng)這個實例所在節(jié)點出現(xiàn)問題需要脫離集群時自動在另一個節(jié)點上構(gòu)建一個同樣的Actor,并重新轉(zhuǎn)交控制。當(dāng)然,由于涉及了一個新構(gòu)建的Actor,內(nèi)部狀態(tài)會在這個過程中丟失。Single-Actor的主要應(yīng)用包括某種對外部只能支持一個接入的程序接口,或者一種帶有由多個其它Actor運算結(jié)果產(chǎn)生的內(nèi)部狀態(tài)的累積型Actor(aggregator)。當(dāng)然,如果使用一種帶有內(nèi)部狀態(tài)的Singleton-Actor,可以考慮使用PersistenceActor來實現(xiàn)內(nèi)部狀態(tài)的自動恢復(fù)。如此Cluster-Singleton變成了一種非常實用的模式,可以在許多場合下應(yīng)用。
Cluster-Singleton模式也恰恰因為它的唯一性特點存在著一些隱憂,需要特別關(guān)注。唯一性容易造成的隱憂包括:容易造成超負(fù)荷、無法保證穩(wěn)定在線、無法保證消息投遞。這些需要用戶在編程時增加特別處理。
好了,我們設(shè)計個例子來了解Cluster-Singleton,先看看Singleton-Actor的功能:
class SingletonActor extends PersistentActor with ActorLogging { import SingletonActor._ val cluster = Cluster(context.system) var freeHoles = 0 var freeTrees = 0 var ttlMatches = 0 override def persistenceId = self.path.parent.name + "-" + self.path.name def updateState(evt: Event): Unit = evt match { &nb