Почему RabbitMQ не сохраняет сообщения в долговременной очереди? - PullRequest
11 голосов
/ 19 февраля 2011

Я использую RabbitMQ с Django через Celery.Я использую самую базовую настройку:

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

Я импортировал задачу Celery и поставил ее в очередь для запуска через год.Из оболочки 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 получил это сообщение в очереди сельдерея:

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

Затем я убил RabbitMQ, нажав control-C, а затем "a" для отмены.Когда я снова запускаю сервер и проверяю его с помощью rabbitmqctl, он говорит, что в очереди сельдерея нет сообщений:

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

Очередь сельдерея была длительной.Почему сообщения не сохранились?Что мне нужно сделать, чтобы сообщения были постоянными?

Ответы [ 2 ]

20 голосов
/ 19 февраля 2011

Создание длительной очереди - это не то же самое, что сделать сообщения в ней постоянными.Долговечные очереди означают, что они снова появляются автоматически после перезапуска сервера - что, очевидно, произошло в вашем случае.Но это не влияет на сами сообщения.

Чтобы сообщения были постоянными, необходимо также пометить свойство сообщения delivery_mode значением 2. См. Классическую запись Кролики и Уоррены для полного объяснения.

Редактировать: Полная ссылка не работает, но по состоянию на декабрь 2013 года вы все еще можете найти сообщение в блоге по основному URL: http://blogs.digitar.com/jjww/

5 голосов
/ 19 февраля 2011

Чтобы узнать сообщения delivery_mode, вы можете использовать его и посмотреть свойства сообщения:

>>> 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'}
...