2011-02-18 137 views
9

我通過芹菜使用Django的RabbitMQ。我正在使用最基本的設置:爲什麼RabbitMQ不會在持久隊列中保存消息?

# 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. 

我然後通過敲擊控制-C隨後 'a' 到中止殺死的RabbitMQ。當我再次啓動服務器,並與rabbitmqctl檢查它,它說,有在芹菜隊列中沒有消息:

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

芹菜隊列是持久的。爲什麼這些消息不會持續?我需要做些什麼才能使這些消息持續存在?

回答

5

要找出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'} 
19

使隊列持久化與持久化消息不一樣。持久的隊列意味着當服務器重新啓動時它們會自動重新啓動 - 這顯然發生在您的案例中。但是這並不影響消息本身。

要使消息持久存在,還必須將消息的delivery_mode屬性標記爲2.有關完整說明,請參見傳統的寫法Rabbits and Warrens

編輯:全鏈路斷開,但隨着2013年12月,你仍然可以找到從主URL博客文章:http://blogs.digitar.com/jjww/

+0

它看起來像交付模式已被設置爲2:add.delivery_mode == 2.此默認不能在芹菜據我所知改變。 – hekevintran 2011-02-18 22:23:14

+0

有沒有方法可以檢查郵件以檢查其傳送模式? – hekevintran 2011-02-18 22:23:37

+0

你使用的是哪種版本的Kombu? (由Celery使用)Kombu 1.0.0有一個錯誤,其中消息delivery_mode未正確設置。 – asksol 2011-02-19 07:21:21

0

你可能只是typo'd您的評論(超過在其他的答案中的一個),但以防萬一:行

add.delivery_mode == 2 

確實不是設置的值爲delivery_mode,因爲==比較Python中的兩個數字;它實際上是分配運算符,它是=。因此,您所引用的聲明將delivery_mode2進行比較,然後丟棄True或(最有可能)False的結果。實際設置的值,使用:

add.delivery_mode = 2 
相關問題