2011-02-18 30 views
9

Estoy usando RabbitMQ con Django a través de Apio. Estoy utilizando la configuración más básica:¿Por qué RabbitMQ no persiste mensajes en una cola duradera?

# RabbitMQ connection settings 
BROKER_HOST = 'localhost' 
BROKER_PORT = '5672' 
BROKER_USER = 'guest' 
BROKER_PASSWORD = 'guest' 
BROKER_VHOST = '/' 

Importé una tarea apio y la cola que se ejecute un año más tarde. Desde el shell IPython:

In [1]: from apps.test_app.tasks import add 

In [2]: dt=datetime.datetime(2012, 2, 18, 10, 00) 

In [3]: add.apply_async((10, 6), eta=dt) 
DEBUG:amqplib:Start from server, version: 8.0, properties: {u'information': 'Licensed under the MPL. See http://www.rabbitmq.com/', u'product': 'RabbitMQ', u'version': '2.2.0', u'copyright': 'Copyright (C) 2007-2010 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.', u'platform': 'Erlang/OTP'}, mechanisms: ['PLAIN', 'AMQPLAIN'], locales: ['en_US'] 
DEBUG:amqplib:Open OK! known_hosts [] 
DEBUG:amqplib:using channel_id: 1 
DEBUG:amqplib:Channel open 
DEBUG:amqplib:Closed channel #1 
Out[3]: <AsyncResult: cfc507a1-175f-438e-acea-8c989a120ab3> 

RabbitMQ recibido este mensaje en la cola de apio:

$ rabbitmqctl list_queues name messages durable 
Listing queues ... 
KTMacBook.local.celeryd.pidbox 0 false 
celery 1 true 
celeryctl_KTMacBook.local 0 true 
...done. 

entonces mataron RabbitMQ golpeando control-C seguido por 'a' para abortar. Cuando inicio el servidor de nuevo y comprobar que funciona con rabbitmqctl, se dice que no hay mensajes en la cola de apio:

$ rabbitmqctl list_queues name messages durable 
Listing queues ... 
celery 0 true 
celeryctl_KTMacBook.local 0 true 
...done. 

La cola de apio fue duradero. ¿Por qué los mensajes no persistieron? ¿Qué debo hacer para que los mensajes sean persistentes?

Respuesta

5

para averiguar los mensajes delivery_mode que puede consumir y mirar las propiedades del mensaje:

>>> from tasks import add 
>>> add.delay(2, 2) 

>>> from celery import current_app 
>>> conn = current_app.broker_connection() 
>>> consumer = current_app.amqp.get_task_consumer(conn) 

>>> messages = [] 
>>> def callback(body, message): 
...  messages.append(message) 
>>> consumer.register_callback(callback) 
>>> consumer.consume() 

>>> conn.drain_events(timeout=1) 

>>> messages[0].properties 
>>> messages[0].properties 
{'application_headers': {}, 'delivery_mode': 2, 'content_encoding': u'binary', 'content_type': u'application/x-python-serialize'} 
+2

Confirmé que el modo de entrega se estableció en 2. Pude hacer que funcionara al actualizar RabbitMQ a 2.3.1. Obtuve los problemas de persistencia al usar RabbitMQ 2.2.0. – hekevintran

19

Hacer que una cola sea duradera no es lo mismo que hacer que los mensajes en ella sean persistentes. Las colas duraderas significan que vuelven a aparecer automáticamente cuando el servidor se reinicia, lo que obviamente ha sucedido en su caso. Pero esto no afecta los mensajes en sí mismos.

Para hacer que los mensajes persistente, hay que también marcan delivery_mode la propiedad del mensaje a 2. Véase el clásico relato Rabbits and Warrens para una explicación completa.

Editar: enlace completo se rompe, pero a Dic de 2013, aún podría encontrar la entrada del blog de la URL principal: http://blogs.digitar.com/jjww/

+0

Parece que el modo de entrega ya está establecido en 2: == add.delivery_mode 2. Este defecto no se puede cambiar en el apio por lo que yo sé. – hekevintran

+0

¿Hay alguna manera de poder inspeccionar el mensaje para verificar su modo de entrega? – hekevintran

+0

¿Qué versión de Kombu estás usando? (utilizado por Aplery) Kombu 1.0.0 tenía un error donde los mensajes delivery_mode no estaban configurados correctamente. – asksol

0

Es posible que haya simplemente typo'd su comentario (más en una de las otras respuestas), pero por si acaso: la línea

add.delivery_mode == 2 

hace no establece el valor delivery_mode, porque == compara dos números en Python; es = que es realmente el operador de asignación. Por lo tanto, la afirmación que cita compara delivery_mode con 2, y luego arroja el True o (lo más probable) False que resulta. Para establecer realmente un valor, utilice:

add.delivery_mode = 2 
+1

Eso fue intencional. Estaba confirmando que el atributo delivery_mode del mensaje era igual a 2. No estaba intentando configurarlo :) – hekevintran

Cuestiones relacionadas