4 votes

"Unknown delivery tag" de RabbitMQ lors de l'acceptation d'un message dans un cluster avec des files d'attente répliquées

Nous utilisons Rabbit avec succès depuis environ un an. Récemment, nous sommes passés à la version 2.6.1, car nous voulons utiliser des clusters avec des files d'attente de messages répliquées.

Mes tests ont mis en évidence un comportement déroutant qui me fait penser à un bug de Rabbit. Le test qui a permis de le découvrir fonctionne avec un cluster à deux noeuds. Les deux nœuds fonctionnent avec la version 2.6.1. Les deux nœuds ont un disque. Les deux nœuds fonctionnent sous Mac OS, bien que je doute que cela soit pertinent.

Je lance également Alice sur le nœud qui exécute le test. Le test l'utilise pour programmer un stop_app sur l'un des nœuds, parce que le test essaie de valider que si le maître du cluster tombe en panne, et qu'un esclave est élevé pour prendre sa place, nous ne perdons pas de messages.

Ainsi, le test dispose d'un petit pool de threads, auquel sont attribuées des tâches qui périodiquement 1) publient des messages, et 2) font basculer l'état du nœud maître Rabbit (arrêté s'il est en cours d'exécution ; démarré s'il est à l'arrêt). D'autres threads consomment des messages provenant de files d'attente.

J'utilise les confirmations de l'éditeur et j'accuse réception des messages dans les consommateurs (en utilisant autoAck=false pour channel.basicConsume()).

Lorsque le nœud maître est arrêté, je vois les producteurs et les consommateurs attraper une ShutdownSignalException. Ils gèrent cette situation en tentant de se reconnecter au cluster. Cela fonctionne bien. Une fois reconnectés, ils poursuivent leur activité.

Parfois, ce que je vois, c'est qu'un consommateur a réussi à récupérer un message du courtier et appelle channel.basicAck() lorsqu'il reçoit cette ShutdownSignalException.

Plus tard, lorsque le consommateur s'est reconnecté, il télécharge à nouveau le même message. (Cette fois, lorsque le consommateur tente de basicAck() le message, il obtient à nouveau une ShutdownSignalException, mais celle-ci contient le texte suivant : "reply-text=PRECONDITION_FAILED - unknown delivery tag 7".

En fait, il s'agit de la même étiquette de livraison qui a été proposée au consommateur par le courtier avant que le maître ne tombe en panne et que le consommateur ne se reconnecte.

D'après les recherches effectuées sur Google, cet événement signifie que le consommateur tente d'accepter le même message plus d'une fois.

Mais comment cela se fait-il ? Si le premier ack a réussi, le message devrait avoir été supprimé des files d'attente du courtier et le consommateur ne devrait plus voir le même message.

Cependant, si le premier ack n'a pas abouti, le consommateur ne devrait pas être pénalisé pour avoir tenté de ré-accuser le message.

Quelqu'un a déjà vu cela ? Pour moi, cela ressemble à un bug dans les files d'attente répliquées de Rabbit, mais je ne connais pas encore Rabbit, et je suis donc prêt à croire qu'il y a une subtilité dans la consommation à partir d'un courtier en grappe que je n'ai pas encore comprise !

Merci, --Steve

4voto

Je ne suis pas sûr que mon cas corresponde au vôtre, mais j'ai vu des "unknown delivery tag" similaires lors de tentatives d'ack après reconnexion, puis le même message est arrivé à nouveau. Au départ, cela m'a semblé être un bogue, mais en fait, il s'agit d'un comportement attendu. Le consommateur avec QOS>1 peut avoir dans son tampon local quelques messages et l'étiquette de livraison sera invalide pour chacun d'entre eux après la reconnexion. D'autre part, la tentative d'acceptation du message actuel après la reconnexion n'a pas de sens, car ce message a déjà été annulé automatiquement lors de la perte de connexion et c'est la raison pour laquelle je l'ai reçu à nouveau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X