2017-10-18 11 views
2

Nous avons une application de cluster Akkka (fragmentation de certains acteurs). Parfois, quand nous déployons et notre application devrait être mis hors que nous voyons certains journaux comme ça:CoordinatedShutdown timeout sur l'application de cluster Akka

phase d'arrêt Coordinated [cluster sharding-arrêt-région] chronométré après 10000 millisecondes

Cette se produit sur le premier déploiement après plus de 2 jours depuis le dernier déploiement (le lundi par exemple). Nous demandons au nœud akka de quitter le groupe avec l'aide JMX et nous avons le code suivant aussi:

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

Ainsi, lorsque cette erreur se produit, éventuellement nœud quitte le cluster (ou du moins il ferme le point d'entrée JMX à gérer le cluster akka) mais le processus ne se termine pas et le journal "Fermeture du nœud" n'apparaît pas. Donc, lorsque cela se produit, nous devons arrêter le processus Java manuellement (nous traitons cela avec le superviseur) et redéployer.

Je sais que le délai d'attente peut être réglé via la configuration, mais quelles sont les implications de l'augmentation de ce délai? Pourquoi parfois une fermeture coordonnée entraîne un dépassement de délai? Que se passe-t-il lorsque le délai d'arrêt coordonné est dépassé?

Un indice serait apprécié: D

Merci

Répondre

0

Nous avons utilisé pour faire face à ce problème (un de la temporisation de phase d'arrêt Coordonné) pour l'application de courte durée.

Utiliser cas où nous avons été confrontés à ceci:

  1. application rejoint cluster akka existant
  2. fait un travail
  3. quitte le cluster

Mais à l'étape 3, le statut de membre était still (Joining ou WeaklyUp) et si vous voyez une tâche ajoutée pour PhaseClusterLeave, cela permet de supprimer un membre du cluster uniquement si son statut est UP.

Snippet de ClusterDaemon.scala qui est invoquée sur la phase en cours ClusterLeave:

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() 
    } 
} 

Pour résoudre ce problème, nous avons fini par écrire notre propre CoordinatedShutdown que vous pouvez consulter ici CswCoordinatedShutdown.scala

1

Qu'est-ce qui se passe après le délai ? Je cite Akka documentation:

Si les tâches ne sont pas terminées dans un délai d'attente configuré (voir reference.conf) la phase suivante sera lancé de toute façon. Il est possible de configurer recover=off pour qu'une phase abandonne le reste du processus d'arrêt si une tâche échoue ou n'est pas terminée dans le délai imparti.

Pourquoi l'arrêt peut-il prendre fin? Très possible, vous avez une impasse quelque part. Dans ce cas, l'augmentation du délai d'attente n'aiderait pas. Il se peut également que vous ayez besoin de plus de temps pour l'arrêter. Ensuite, vous devez augmenter le délai d'expiration.

Mais plus lié à votre problème, pourrait être la suivante:

Par défaut, la machine virtuelle Java est pas empêché par la force (il sera arrêté si tous les threads non-démon ont été mis fin). Pour activer un System.exit dur comme une action finale, vous pouvez configurer:

akka.coordinated-shutdown.exit-jvm = on 

Vous pouvez l'activer, ce qui devrait résoudre le « arrêt du processus java manuellement » étape. Néanmoins, la question difficile est de savoir pourquoi la temporisation expire en premier lieu. Je suppose qu'avec l'astuce ci-dessus, vous pouvez survivre pendant un certain temps, mais vous feriez mieux de passer du temps à trouver la cause réelle.