13

我有一个演员池正在使用的共享外部资源(比如文件存储)。每次对文件存储发出新请求时,都会创建一个新参与者,以使用传入的外部系统的引用来填充请求。

我为每个参与者创建一个断路器的当前方法违背了目的,因为为每个“请求”创建了一个新参与者,该“请求”对该外部资源执行一系列操作。

不理想 - 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()
   }
} 

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

4

1 回答 1

11

是的,遵循这种方法是安全的。我们在对同一主机进行 http 调用的相关参与者(池化或其他)之间共享断路器。如果您不这样做,并让每个实例都有自己的断路器,即使它们是长期存在的实例,每个实例都需要在断路器打开之前分别达到失败阈值,我怀疑这是您想要的行为。通过共享,它允许多个参与者将统计信息(失败、成功)贡献给断路器,以便断路器代表已进入资源的所有调用。

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

于 2014-06-18T18:31:07.443 回答