2017-04-20 47 views
0

我有小的混亂在我的腦海 避免中毒郵箱 http://doc.akka.io/docs/akka/2.4.2/general/supervision.html阿卡持久,恢復失敗,至少一次語義

然後,新的演員繼續處理其郵箱,這意味着 重啓在演員本身之外是不可見的,除了發生故障的消息不是 重新處理之外,值得注意的 例外。

我的情況:actor收到「命令」運行smth。演員試圖達到遠程服務。服務不可用。拋出異常。我希望演員繼續聯繫遠程服務器。我不希望演員跳過導致異常的輸入命令。請問簡歷幫我強制演員繼續走下去嗎?

override val supervisorStrategy: SupervisorStrategy = 
    OneForOneStrategy(maxNrOfRetries = -1, withinTimeRange = 5.minutes) { 
     case _: RemoteServiceIsDownException => Resume 
     case _ => Stop 
    } 

通過恢復,我的意思是重試導致異常被拋出調用。我懷疑,阿卡恢復手段不斷演員實例,但不重試失敗的調用

難道阿卡持久耐用意味着郵箱?

擴展第一種情況。演員試圖達到遠程服務。現在演員是持久的。 SupervisorStrategy強制Actor繼續聯繫遠程服務。整個JVM關閉。 Akka應用程序重新啓動。演員恢復從它疲憊地拼命到達遠程服務的地步?

akka持久性意味着至少一次語義?

演員收到消息。然後JVM崩潰。父母是否會重新收到在戀愛期間正在處理的消息?

+0

通過「簡歷」,你的意思重試導致異常被拋出調用? 使用Akka持久性爲您提供了實現持久郵箱的工具,但是您不通過擴展'PersistentActor'來獲得這些。該工具包提供了一個非常棒的特徵,叫做「AtleastOnceDelivery」,它可以幫助你或多或少完成你所描述的內容 - http://doc.akka.io/docs/akka/current/scala/persistence.html#At-Least -Once_Delivery – simonl

+0

'resume',你的意思是重試導致異常被引發的調用? - 是的。 – Sergey

回答

1

擴大我的評論:

將繼續幫助我,迫使演員堅持下去? ...通過簡歷,我的意思是重試導致異常被引發的調用。我懷疑akka簡歷意味着保留演員實例,但不重試失敗調用

不,我不這麼認爲。在你的消息處理失敗後,Resume指令將使演員繼續前進。雖則重試消息的一種方式,是實際只使用Restart,並採取一個ActorpreRestart掛鉤的優勢:

override def preRestart(t: Throwable, msgBeforeFailure: Option[Any]): Unit = { 
    case t: RemoteServiceIsDownException if msgBeforeFailure.isDefined => 
    self ! msgBeforeFailure.get 
    case _: => 
} 

當演員崩潰,它將運行這個鉤子,併爲您提供了一個機會來處理導致它失敗的消息。

akka持久性意味着持久的郵箱嗎?

不一定,使用持久性actor只是意味着actor的域事件,隨後內部狀態是持久的,而不是它用來處理消息的郵箱。話雖如此,可以很容易地實現一個耐用的郵箱,見下文。

確實akka是否意味着至少一次語義?

再次不一定,但該工具包確實有一個名爲AtleastOnceDelivery的特點,可以讓您實現這個(和耐用郵箱)!

http://doc.akka.io/docs/akka/current/scala/persistence.html#At-Least-Once_Delivery

+0

真棒,謝謝,我錯過了文檔中的AtleastOnceDelivery特質並且不知道msgBeforeFailure – Sergey

+0

請注意,重新發送導致演員崩潰/重新啓動的消息可能是危險的,如果崩潰的原因是消息 - 演員只會再次崩潰並重復。 – johanandren