Comment puis-je définir un certain nombre de tentatives de nouvelle tentative dans RabbitMQ?

J'utilise RabbitMQ et j'ai une file d'attente qui contient des messages électroniques. Mon service consommateur désactive les messages et tente de les envoyer. Si, pour une raison quelconque, mon consommateur ne peut pas envoyer le message, je voudrais re-mettre en file d'attente le message à envoyer à nouveau. Je me rends compte que je peux faire un basicNack et définir le drapeau requeue pour être vrai, cependant, je ne veux pas requeue le message indéfiniment (disons, si notre système de messagerie tombe en panne, Je ne veux pas requeue continuellement les messages non envoyés). Je voudrais définir une nombre fini de fois que je peux requeue le message à envoyer à nouveau. Je ne peux pas définir un champ sur l'objet de message électronique, cependant, quand je le désqueue et envoie un nack. Le champ mis à jour n'est pas présent sur le message dans la file d'attente. Est-il un autre moyen dans lequel je peux m'approche de cela? Merci à l'avance.

33
demandé sur user2689570 2014-04-18 20:39:41

1 réponses

Il N'y a pas de fonctionnalité telle que les tentatives de nouvelle tentative dans RabbitMQ (ainsi que dans le protocole AMQP).

Solution Possible pour implémenter le comportement limite des tentatives de nouvelle tentative:

  1. Redeliver le message s'il n'a pas déjà été redelivré (vérifiez le paramètre redelivered sur la méthode basic.deliver - votre bibliothèque devrait avoir une interface pour cela) et déposez-le, puis attrapez échange de lettres mortes , puis traitez d'une manière ou d'une autre.

  2. Chaque fois que le message ne peut pas être traité publiez le à nouveau mais définir ou incrémenter / décrémenter le champ d'en-tête, disons x-redelivered-count (Vous pouvez choisir n'importe quel nom que vous aimez, cependant). Pour avoir le contrôle sur les redeliveries dans ce cas, vous devez vérifier le champ que vous définissez s'il atteint une limite (top ou bottom - 0 est mon choix, a-la ttl dans l'en-tête ip de tcp/ip).

  3. Stocker une clé unique de message (disons uuid, mais vous devez la définir manuellement lorsque vous publiez un message) dans Redis, memcache ou un autre stockage, même dans mysql aux côtés de redeliveries count, puis sur chaque redelivery incrémente / décrémente cette valeur jusqu'à ce qu'elle atteigne la limite.

  4. (pour les vrais geeks) écrire un plugin qui mettra en œuvre un tel comportement comme vous le souhaitez.

Le pro de #3 est-ce que ce message redélivré reste en tête de file d'attente. Ceci est important si vous avez une longue file d'attente ou si l'ordre des messages est important pour vous (notez que les redeliveries vont casser l'ordre strict des messages, voir les documents officiels pour plus de détails ou cette question sur Donc).

P. S.:

Il y a réponse similaire dans ce sujet, mais en php. Regardez à travers, peut-être que cela vous aide un peu (commencez à le lire à partir des mots "Il existe plusieurs techniques pour traiter le problème de redeliver de cycle".

46
répondu pinepain 2017-05-23 12:25:55