Akka相当于Spring InitializingBean

时间:2016-04-22 13:58:51

标签: akka

我已经编写了一些actor类,我发现我必须处理这些实体的生命周期。例如,每当我的actor被初始化时,我想要一个方法被调用,以便我可以在消息队列(或打开数据库连接等)上设置一些监听器。

有相同的吗?我能想到的是Spring的InitialisingBean和DisposableBean

2 个答案:

答案 0 :(得分:1)

Actor基本上是两种方法 - 构造函数和onMessage(Object): void

在其生命周期中没有任何东西可以自然地提供“布线”行为,这为您提供了一些选择。

  1. 使用主管演员创建其他演员。主管负责观察,启动和重启Actors失败 - 因此让主管了解集成系统的状态以避免不断重启通常很有价值。该Supervisor将创建和管理Service对象(可能通过Spring)并将它们传递给Actors。

  2. 在演员构建时使用您首选的初始化技术。这很棘手,但您当然可以将Spring与Actors结合使用。请注意,如果主管重新启动您的演员,您需要能够从您在首先启动它的Props对象中放置的任何内容中恢复其所需的状态。

  3. 按需连接所有内容。在Actor启动时按需打开连接(并根据需要缓存它们)。我发现我经常这样做 - 当它的连接不再起作用时,我让Actor失败了。主管将重新启动Actor,这将重新创建所有连接。

  4. 要记住的重要事项:

    • Actor模型的目的是Actors不会连续运行 - 它们只在提供消息时运行。如果向Actor添加消息侦听器,则实质上是添加可以访问该actor的新线程。如果您使用监督,这可能是一个问题 - 重新启动的actor可能泄漏该线程,这可能反过来导致该actor不被垃圾收集。它也可能是一个问题,因为它引入了竞争条件,并且演员的一部分价值就是避免这种情况。
    • 从演员系统的角度来看,执行I / O的Actor是阻塞的。如果有太多Actors同时执行I / O操作,您将耗尽Dispatcher的线程池并锁定系统。
    • 给定的Actor实例可以在其生命周期内在许多不同的线程上运行,但一次只能在一个线程上运行。这可能会使某些消息传递系统感到困惑 - 例如,JMS'Spec断言Session不能在多个线程上使用,而且许多JMS将其解释为“只能在启动它的线程上运行”。您可能会看到由此产生的警告甚至异常。
    • 由于这些原因,我更喜欢使用非演员代码来完成我的一些I / O.例如,我将有一个传入的消息监听器对象,其职责是将JMS消息从队列中取出,使用它们来创建POJO消息,并将告知发送给Actor系统。或者,我将使用Actor,但将该actor放在启用了线程固定的自定义Dispatcher上。这确保了Actor只能在特定线程上运行,并且不会阻塞其他非I / O actor正在使用的系统。

答案 1 :(得分:1)

这是一个典型的情况,您override methodspreStart()postStop()等。我不会发现此问题。

当然,您必须了解详细信息 - 例如,在调用postStop()之后异步调用actor.stop(),而在启动Actor时调用preStart()。这意味着数据库交互等潜在的缓慢/阻塞应该保持在最低限度。

您还可以使用Actor的构造函数来初始化数据。

正如Matthew所说,监督在Akka中起着重要作用 - 因此您可以指示主管在事件中执行特定的事情。例如,所谓的 DeathWatch - 如果其中一位演员正在观看"你可以得到通知。模具:

context.watch(child)

...

def receive = {
    case Terminated(`child`) => lastSender ! "finished"
}