Akka Kill、Stop和Poison Pill之间有什么区别?

224

关于Akka的新手问题 - 我正在阅读《Akka Essentials》,请问有人能解释一下Akka Stop/Poison Pill和Kill之间的区别吗?书中只是简单地解释了一下“Kill是同步的,而Poison pill是异步的。”但是在哪些方面呢? 在此期间,调用actor线程是否会锁定?在Kill、post-stop被调用时,子actor是否会收到通知?一个概念与另一个概念的示例用法有什么不同?

非常感谢!


12
rs_atl已经很好地回答了这个问题,让我补充一点:演员的任何事情都不是同步的,甚至包括context.stop(self)。 - Roland Kuhn
1
@RolandKuhn context.become 怎么样? - Ionuț G. Stan
3
context.become指定了将应用于下一条消息的行为,这意味着它会在当前消息被处理完毕之后生效;在这方面它类似于context.stop(self) - Roland Kuhn
4个回答

341

stopPoisonPill 都会终止actor并停止消息队列。它们将导致actor停止处理消息,向所有子节点发送停止调用,等待它们终止,然后调用其postStop hook。所有进一步的消息都将被发送到死信邮箱。

区别在于在此序列开始之前处理哪些消息。在调用stop时,当前正在处理的消息首先完成,所有其他消息都将被丢弃。当发送PoisonPill时,这只是队列中的另一个消息,因此当接收到PoisonPill时序列将开始。队列中排在其前面的所有消息都将首先得到处理。

相比之下,Kill消息会导致actor抛出一个ActorKilledException,使用正常的supervisor机制进行处理。因此,这里的行为取决于您在监管策略中定义的内容。默认值是停止actor。但是邮箱仍然存在,因此当actor重新启动时,它仍将具有旧消息,除了导致失败的那个消息。

还可以查看文档中的“停止actor”、“杀死actor”部分:

http://doc.akka.io/docs/akka/snapshot/scala/actors.html

以及有关监管策略的更多信息:

http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html


4
非常好的回答,谢谢!应该发布在Akka教程上! - LaloInDublin
18
除非您使用非默认监管策略,否则“Kill”消息不会导致Actor使用正常的监管机制重新启动,因为ActorKilledException解析为Stop而不是Restart。 - lisak
实际上这很烦人,因为重新启动演员的唯一内置方法是抛出异常。 - lisak
1
或者从监督actor向应该被重新启动的actor发送PoisonPill并重新启动它。 - lisak
1
值得注意的是,在使用具有“Stash”特性的Actor时,使用“PosionPill”可能会导致在Actor未取消存储任何已存储消息之前自动处理“PoisonPill”。请参见http://doc.akka.io/docs/akka/current/scala/persistence.html#Safely_shutting_down_persistent_actors。 - David
显示剩余3条评论

1

尽可能使用PoisonPill。它被放置在邮箱中并像任何其他信件一样被消耗。您也可以在actor内部使用"context.stop(self)"。


0

PoisonPill 是一种异步方式,它会在处理完邮箱中 PoisonPill 之前的所有消息后停止 Actor。


20
不,Kill 没有任何特殊的优先级,就像 PoisonPill 一样。 - Roland Kuhn

0

您可以使用actor stop和poison pill来停止actor的处理,使用kill来完全终止actor。 x.stop是在akka receive方法中调用的,只会在调用postStop后将actor状态替换为新的actor。 x!PoisonPill是一种方法,您可以将其传递给正在运行的actor以停止处理(推荐使用)。在调用postStop后也会替换actor状态。 x.kill将终止actor并将actor从actor路径中删除,并用新的actor替换整个actor。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接