web-dev-qa-db-fra.com

Comment récupérer des messages AMQP non acquittés à partir d'autres canaux que ceux de ma connexion?

Il semble que plus mon serveur rabbitmq fonctionne longtemps, plus j'ai de problèmes avec les messages non acquittés. J'aimerais les remettre en file d'attente. En fait, il semble y avoir une commande amqp pour ce faire, mais elle ne s'applique qu'au canal que votre connexion utilise. J'ai construit un petit script pika pour au moins l'essayer, mais il me manque quelque chose ou cela ne peut pas être fait de cette façon (que diriez-vous de rabbitmqctl?)

import pika

credentials = pika.PlainCredentials('***', '***')
parameters = pika.ConnectionParameters(Host='localhost',port=5672,\
    credentials=credentials, virtual_Host='***')

def handle_delivery(body):
    """Called when we receive a message from RabbitMQ"""
    print body

def on_connected(connection):
    """Called when we are fully connected to RabbitMQ"""
    connection.channel(on_channel_open)    

def on_channel_open(new_channel):
    """Called when our channel has opened"""
    global channel
    channel = new_channel
    channel.basic_recover(callback=handle_delivery,requeue=True)    

try:
    connection = pika.SelectConnection(parameters=parameters,\
        on_open_callback=on_connected)    

    # Loop so we can communicate with RabbitMQ
    connection.ioloop.start()
except KeyboardInterrupt:
    # Gracefully close the connection
    connection.close()
    # Loop until we're fully closed, will stop on its own
    connection.ioloop.start()
44
Will Olbrys

Les messages non acquittés sont ceux qui ont été livrés sur le réseau à un consommateur mais qui n'ont pas encore été acquittés ou rejetés - mais ce consommateur n'a pas encore fermé le canal ou la connexion sur laquelle il les a reçus à l'origine. Par conséquent, le courtier ne peut pas déterminer si le consommateur prend juste beaucoup de temps pour traiter ces messages ou s'il les a oubliés. Ainsi, cela les laisse dans un état non reconnu jusqu'à ce que le consommateur meure ou qu'il soit acquitté ou rejeté.

Étant donné que ces messages pourraient encore être valablement traités à l'avenir par le consommateur encore vivant qui les a consommés à l'origine, vous ne pouvez pas (à ma connaissance) insérer un autre consommateur dans le mélange et essayer de prendre des décisions externes à leur sujet. Vous devez obliger vos consommateurs à prendre des décisions sur chaque message au fur et à mesure qu'ils sont traités plutôt que de laisser les anciens messages non reconnus.

64
Brian Kelly

Si les messages ne sont pas empilés, il n'y a que deux façons de les remettre dans la file d'attente:

  1. basic.nack

    Cette commande entraînera la remise du message dans la file d'attente et sa remise.

  2. Se déconnecter du courtier

    Cette action forcera tous les messages non empilés de ce canal à être remis dans la file d'attente.

[~ # ~] note [~ # ~] : basic.recover va essayer de republier les messages non empilés sur le même canal (pour le même consommateur), qui est parfois le comportement souhaité.

spécification RabbitMQ pour basic.recover et basic.nack


La vraie question est: pourquoi les messages ne sont-ils pas reconnus?

Scénarios possibles pour provoquer des messages non empilés:

  1. Le consommateur récupère trop de messages, puis ne les traite pas et ne les acquitte pas assez rapidement.

    Solution: Prérécupérez le moins de messages possible.

  2. Bibliothèque cliente buggy (j'ai ce problème actuellement avec pika 0.9.13 . Si la file d'attente contient beaucoup de messages, un certain nombre de messages resteront bloqués non chargé, même quelques heures plus tard.

    Solution: je dois redémarrer le consommateur plusieurs fois jusqu'à ce que tous les messages non empilés soient partis de la file d'attente.

19
IvanD

Tous les messages non acquittés passeront à l'état prêt une fois que tous les travailleurs/consommateurs seront arrêtés.

Assurez-vous que tous les employés sont arrêtés en confirmant avec un grep sur ps aux sortie, et les arrêter/les tuer s'ils sont trouvés.

Si vous gérez des travailleurs à l'aide de superviseur, ce qui indique que le travailleur est arrêté, vous pouvez vérifier les zombies. Le superviseur signale que le travailleur est arrêté, mais vous trouverez toujours des processus zombies en cours d'exécution lorsqu'ils sont attendus sur la sortie ps aux. Tuer les processus zombies ramènera les messages à l'état prêt.

4
Venkat Kotra