在正式的生產(chǎn)環(huán)境中皂冰,我們不想丟失任何任務痊夭,如果有一個消費者掛掉了,那么我們應該將分發(fā)給它的任務交付給另一個消費者去處理。 為了確保消息不會丟失过咬,RabbitMQ支持消息應答。消費者發(fā)送一個消息應答制妄,告訴RabbitMQ這個消息已經(jīng)接收并且處理完畢了掸绞。RabbitMQ可以刪除它了。
那么如何設置RabbitMQ為手動應答模式呢耕捞?
1衔掸、Message acknowledgment(消息應答)
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
boolean autoAck = true;
(自動確認模式)一旦RabbitMQ將消息分發(fā)給了消費者,就會從內(nèi)存中刪除俺抽。在這種情況下敞映,如果殺死正在執(zhí)行任務的消費者,會丟失正在處理的消息磷斧,也會丟失已經(jīng)分發(fā)給這個消費者但尚未處理的消息振愿。boolean autoAck = false;
(手動確認模式) 我們不想丟失任何任務,如果有一個消費者掛掉了弛饭,那么我們應該將分發(fā)給它的任務交付給另一個消費者去處理冕末。 為了確保消息不會丟失,RabbitMQ支持消息應答侣颂。消費者發(fā)送一個消息應答档桃,告訴RabbitMQ這個消息已經(jīng)接收并且處理完畢了。RabbitMQ可以刪除它了憔晒。- 消息應答是默認打開的藻肄。也就是
boolean autoAck =false;
2、Message durability(消息持久化)
我們已經(jīng)了解了如何確保即使消費者死亡拒担,任務也不會丟失嘹屯。但是如果RabbitMQ服務器停止,我們的任務仍將失去澎蛛!當RabbitMQ退出或者崩潰抚垄,將會丟失隊列和消息。除非你不要隊列和消息谋逻。兩件事兒必須保證消息不被丟失:我們必須把“隊列”和“消息”設為持久化呆馁。
boolean durable = true;
channel.queueDeclare("hrabbit_queue_work", durable, false, false, null);
這里有一點需要注意的問題,我們直接把durable的false改成true就可以了嗎毁兆?因為我現(xiàn)在運行的程序中已經(jīng)存在了hrabbit_queue_work
這個隊列浙滤,當我再次執(zhí)行的時候,會拋出如下的異常
channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'hrabbit_queue_work'
盡管這行代碼是正確的气堕,他不會運行成功纺腊。因為我們已經(jīng)定義了一個名叫hrabbit_queue_work的未持久化的隊列畔咧。RabbitMQ不允許使用不同的參數(shù)設定重新定義已經(jīng)存在的隊列,并且會返回一個錯誤揖膜。 一個快速的解決方案——就是聲明一個不同名字的隊列誓沸,比如task_queue∫妓冢或者我們登錄控制臺將隊列刪除就可以了拜隧。
系列文章:
RabbitMQ:RabbitMQ-理論基礎
RabbitMQ:快速入門hello word
RabbitMQ:RabbitMQ:work queues 工作隊列(Round-robin/Fair dispatch)
RabbitMQ:發(fā)布/訂閱 Publish/Subscribe
RabbitMQ:路由Routing
RabbitMQ:Topic類型的exchange
RabbitMQ:RabbitMQ之消息確認機制(事務+Confirm)
RabbitMQ:spring整合RabbitMQ