2014-06-18 59 views
12

我有一個演員正在使用的共享外部資源(比如文件存儲)。每次向文件存儲器發出新的請求時,都會創建一個新的參與者以填充請求,並引用傳入的外部系統。Akka Circuit Breaker在演員之間分享

當前我爲每個參與者創建斷路器的方法違背了作爲爲每個對這個外部資源執行一系列操作的'請求'創建新的actor。

不理想 - 太多的CB實例;

class MySharedResourceActor(externalResourceRef: ExtSystem) extends Actor with ActorLogging { 
    val breaker = new CircuitBreaker(context.system.scheduler, 
    maxFailures = 5, 
    callTimeout = 10.seconds, 
    resetTimeout = 1.minute).onOpen(notifyMeOnOpen()) 

    def receive = { 
     case SomeExternalOp => 
      breaker.withSyncCircuitBreaker(dangerousCallToExternalSystem()) pipeTo sender() 
    } 
} 

較好的方法 - 通過在CB REF;

class MySharedResourceActor(externalResourceRef: ExtSystem, val breaker: CircuitBreaker) extends Actor with ActorLogging { 
    def receive = { 
     case SomeExternalOp => 
      breaker.withSyncCircuitBreaker(dangerousCallToExternalSystem()) pipeTo sender() 
    } 
} 

它是安全的從父演員也保持與外部系統的引用,並在路由器池共享多個參與者之間的這種斷路器斷路器引用傳遞,動態創建或以其他方式?

回答

9

是的,按照這種方法是安全的。我們與相關的參與者(彙集或其他)共享斷路器,這些參與者正在向同一主機發起http呼叫。如果你沒有這樣做,並且讓每個實例都有自己的斷路器,即使它們是長期存在的實例,每個實例在斷路器打開之前都需要單獨達到失敗閾值,我懷疑這是你想要的行爲。通過共享,它允許多個參與者向斷路器中貢獻統計信息(失敗,成功),以便斷路器代表已經進入資源的所有呼叫。

在查看Akka的代碼時,他們使用斷路器內部的原子來表示狀態並處理狀態轉換,因此它們應該可以安全地用於多個參與者。