Akka的Actor生命周期《Eight》译

  Actor在创建时出现,然后在用户请求时停止。每当一个Actor停止时,它的所有孩子也会被递归停止。此行为极大地简化了资源清理,并有助于避免资源泄漏,例如由打开的套接字和文件引起的资源泄漏。事实上,处理低级多线程代码时常常被忽视的困难是各种并发资源的生命周期管理。

    要停止一个Actor,推荐的模式是在Actor内部调用getContext().stop(getSelf())来自行停止,通常作为对某些用户定义的停止消息的响应,或者当Actor完成其作业时。通过调用getContext().stop(actorRef)技术上可以阻止另一个Actor,但是以这种方式阻止任意Actor是一种不好的做法:尝试向它们发送PoisonPill或自定义停止消息。

    Akka Actor API公开了许多可以在Actor实现中覆盖的生命周期方法,最常用的是preStart()和postStop()。

  • preStart():在actor开始之后但在它处理第一条消息之前调用。
  • postStop():在actor停止之前调用。此后不会处理任何消息。

    让我们在一个简单的实验中使用preStart()和postStop()生命周期方法来观察停止Actor时的行为。首先,将以下2个Actor类添加到项目中:

    并创建一个像上面这样的“main”方法来启动,然后向他们发送一个“停止”消息:

    您可以再次使用sbt来启动此程序。输出应如下所示:

    当我们首先停止Actor时,它停止了它的子Actor,第二,在停止之前。这种排序是严格的,在调用父级的postStop()之前调用子级的所有postStop()。

    Akka参考手册的Actor生命周期( Actor Lifecycle )部分提供了关于全生命周期的详细信息。

异常处理

    父和子在整个生命周期中都是相互联系的。每当Actor失败(抛出一个异常或未处理的异常从接收中冒出来)时,它就会被暂时挂起。如前所述,失败信息被传播到父进程,然后由父进程决定如何处理由子Actor引起的异常。在这种情况下,父充当子的监督者。默认的监督策略是停止并重新启动子进程。如果不更改默认策略,则所有失败都会导致重新启动。

    让我们在一个简单的实验中观察默认策略。将以下类添加到项目中,就像之前的类一样:

    并运行:

    输出:

    我们看到失败后,受监督的Actor被停止并立即重新启动。我们还看到一个日志条目,报告处理的异常,在本例中是我们的测试异常。在这个例子中,我们使用preStart()和postStop(),它们是在重启之后和之前调用的默认值,因此我们无法区分actor内部是第一次启动还是重新启动。这通常是正确的做法,重新启动的目的是将actor设置为已知良好状态,这通常意味着一个干净的起始阶段。实际发生的是调用了preRestart()和postRestart()方法,如果没有被覆盖,默认情况下分别委托给postStop()和preStart()。您可以尝试覆盖这些其他方法,并查看输出如何更改。

    对于感兴趣的人,我们还建议您查看监督参考页面(supervision reference page )以获得更深入的详细信息。

概要

    我们已经了解了Akka如何在层级中管理Actor,父Actor监督孩子Actor并处理异常。我们看到了如何创建一个非常简单的Actor和孩子Actor。接下来,我们将通过建模从设备Actor获取信息所需的通信来将这些知识应用于我们的示例用例。稍后,我们将讨论如何管理团队中的Actor。

原文:https://doc.akka.io/docs/akka/current/guide/tutorial.html

有什么讨论的内容,可以加我公众号:

猜你喜欢

转载自blog.csdn.net/woshiyexinjie/article/details/82429961
今日推荐