【发布时间】:2021-12-27 14:31:08
【问题描述】:
我有一个 Spring Boot 应用程序,当我停止 Spring Boot 应用程序时,即使他们有要处理的消息,akka 演员也会被终止。我想改变行为并希望即使在春季启动应用程序关闭之后,如果那个akka演员有它应该处理的消息并且之后它应该被终止,我尝试了很多事情但没有任何运气,我尝试了优雅关闭弹簧靴。
我们将不胜感激。
提前谢谢????
【问题讨论】:
标签: java spring-boot akka
我有一个 Spring Boot 应用程序,当我停止 Spring Boot 应用程序时,即使他们有要处理的消息,akka 演员也会被终止。我想改变行为并希望即使在春季启动应用程序关闭之后,如果那个akka演员有它应该处理的消息并且之后它应该被终止,我尝试了很多事情但没有任何运气,我尝试了优雅关闭弹簧靴。
我们将不胜感激。
提前谢谢????
【问题讨论】:
标签: java spring-boot akka
我不知道有什么开箱即用的方法来实现这一点,但您可以让您的演员使用custom mailbox,它有一个MessageQueue,当邮箱的空置发生变化时,它会通知全局演员。该全局参与者跟踪哪些参与者在邮箱中至少有一条消息。然后,您注册一个协调的关闭挂钩,该挂钩基本上会在没有具有至少一条消息的演员时要求该演员完成未来。
请注意,由于参与者可以在处理消息的过程中向自己或其他参与者发送任意多条消息,因此无法保证永远不会有参与者在其各自的邮箱中拥有消息的情况。因此,您可能希望有一些方法来指导您的演员开始使用需要发送更少的转发消息的处理定义;因此,这类事情必须为您的应用程序定制,并适合您试图通过应用程序解决的问题(并且不能保证存在这样的处理定义)。
出于这个原因,更符合 Akka 习惯的做法是接受消息的传递和处理通常不能保证永远发生。
【讨论】:
您可以为此使用协调关闭 (https://doc.akka.io/docs/akka/current/coordinated-shutdown.html)。
您可以在PreDestroy 回调中终止系统,例如:
CoordinatedShutdown.get(system)
.runAll(CoordinatedShutdown.jvmExitReason())
.get(60, TimeUnit.SECONDS);
然后你可以按如下方式注册你的演员:
CoordinatedShutdown.get(system())
.addCancellableTask(
CoordinatedShutdown.PhaseServiceRequestsDone(),
"shutdown-actor",
() -> {
return Patterns.ask(self, new Stop(), Duration.ofSeconds(60))
.thenApply(msg -> Done.getInstance());
});
这将推迟系统关闭,直到收到对停止的响应
【讨论】: