演员之间的Akka Circuit Breaker分享

时间:2014-06-18 15:51:27

标签: scala akka actor circuit-breaker

我有一个共享的外部资源(比如一个文件存储),一个actor正在使用它。每次向文件存储区发出新请求时,都会创建一个新的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参考;

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

传递来自父actor的断路器参考是否安全,该参与者还维护对外部系统的引用并在路由器池中的多个actor之间共享此断路器,动态创建或以其他方式?

1 个答案:

答案 0 :(得分:10)

是的,遵循这种方法是安全的。我们共享正在向同一主机进行http调用的相关参与者(池化或其他)的断路器。如果你没有这样做,让每个实例拥有它自己的断路器,即使它们是长寿命的实例,每个实例都需要在断路器打开之前单独达到故障阈值,我怀疑这是你想要的行为。通过共享,它允许多个参与者向断路器提供统计数据(失败,成功),以便断路器代表已进入资源的所有呼叫。

在查看Akka的代码时,他们使用断路器内部的原子来表示状态和处理状态转换,因此它们应该可以安全地用于多个演员。