Akka集群应用程序上的CoordinatedShutdown超时



我们有一个akka集群应用程序(对一些参与者进行分片)。有时,当我们部署并关闭应用程序时,我们会看到一些类似的日志:

协调关闭阶段[集群分片关闭区域]已定时在10000毫秒后退出

自上次部署后超过2天的第一次部署时(例如星期一)会发生这种情况。我们要求akka节点使用JMX助手退出集群,我们也有以下代码:

actorSystem.registerOnTermination {
logger.error("Gracefully shutdown of node")
System.exit(0)
}

因此,当这个错误发生时,节点最终会离开集群(或者至少它关闭了JMX入口点来管理akka集群),但进程没有完成,日志"节点的优雅关闭"也不会出现。因此,当这种情况发生时,我们需要手动关闭java进程(我们与supervisor一起处理)并重新部署。

我知道超时可以通过配置来调整,但增加这个超时有什么意义?为什么有时协调关闭会导致超时?协调关闭超时时会发生什么?

任何线索都将不胜感激:D

谢谢

超时后会发生什么?引用Akka文件:

如果任务没有在配置的超时内完成(请参阅reference.conf),那么下一阶段仍将启动。如果任务失败或未在超时时间内完成,可以为某个阶段配置recover=off以中止关闭过程的其余部分。

为什么关闭可能超时?很可能你在某个地方陷入僵局。在这种情况下,增加超时时间没有帮助。也可能是你需要更多的时间来关闭。然后,您必须增加超时时间。

但与您的问题更相关的可能是以下内容:

默认情况下,JVM不会强制停止(如果所有非守护进程线程都已终止,则JVM将停止)。要启用硬System.exit作为最终操作,您可以配置:

akka.coordinated-shutdown.exit-jvm = on

因此,您可以打开它,这将解决"手动关闭java进程"的步骤。


然而,最困难的问题是首先找出关闭超时的原因。我想有了上面的技巧,你可以活一段时间,但你最好花一些时间找到真正的原因。

我们曾经在短寿命应用程序中遇到过这个问题(协调关闭阶段超时之一)。

我们面临的用例:

  1. 应用程序加入现有的akka集群
  2. 做一些工作
  3. 离开群集

但在步骤3,成员的状态仍然是(Joining或WeaklyUp),如果您看到为PhaseClusterLeave添加了任务,则仅当其状态为UP时,它才允许从集群中删除成员。

在运行ClusterLeave阶段调用的ClusterDaemon.scala中的代码段:

def leaving(address: Address): Unit = {
// only try to update if the node is available (in the member ring)
if (latestGossip.members.exists(m ⇒ m.address == address && m.status == Up)) {
val newMembers = latestGossip.members map { m ⇒ if (m.address == address) m.copy(status = Leaving) else m } // mark node as LEAVING
val newGossip = latestGossip copy (members = newMembers)
updateLatestGossip(newGossip)
logInfo("Marked address [{}] as [{}]", address, Leaving)
publishMembershipState()
// immediate gossip to speed up the leaving process
gossip()
}
}

为了解决这个问题,我们最终编写了自己的CoordinatedShutdown,您可以在这里参考CswCoordinated Shutdown.scala

相关内容

  • 没有找到相关文章

最新更新