
在正式的生產(chǎn)環(huán)境中,我們不想丟失任何任務(wù),如果有一個(gè)消費(fèi)者掛掉了,那么我們應(yīng)該將分發(fā)給它的任務(wù)交付給另一個(gè)消費(fèi)者去處理。 為了確保消息不會(huì)丟失,RabbitMQ支持消息應(yīng)答。消費(fèi)者發(fā)送一個(gè)消息應(yīng)答,告訴RabbitMQ這個(gè)消息已經(jīng)接收并且處理完畢了。RabbitMQ可以刪除它了。
那么如何設(shè)置RabbitMQ為手動(dòng)應(yīng)答模式呢?
1、Message acknowledgment(消息應(yīng)答)
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
boolean autoAck = true;(自動(dòng)確認(rèn)模式)一旦RabbitMQ將消息分發(fā)給了消費(fèi)者,就會(huì)從內(nèi)存中刪除。在這種情況下,如果殺死正在執(zhí)行任務(wù)的消費(fèi)者,會(huì)丟失正在處理的消息,也會(huì)丟失已經(jīng)分發(fā)給這個(gè)消費(fèi)者但尚未處理的消息。boolean autoAck = false;(手動(dòng)確認(rèn)模式) 我們不想丟失任何任務(wù),如果有一個(gè)消費(fèi)者掛掉了,那么我們應(yīng)該將分發(fā)給它的任務(wù)交付給另一個(gè)消費(fèi)者去處理。 為了確保消息不會(huì)丟失,RabbitMQ支持消息應(yīng)答。消費(fèi)者發(fā)送一個(gè)消息應(yīng)答,告訴RabbitMQ這個(gè)消息已經(jīng)接收并且處理完畢了。RabbitMQ可以刪除它了。- 消息應(yīng)答是默認(rèn)打開的。也就是
boolean autoAck =false;
2、Message durability(消息持久化)
我們已經(jīng)了解了如何確保即使消費(fèi)者死亡,任務(wù)也不會(huì)丟失。但是如果RabbitMQ服務(wù)器停止,我們的任務(wù)仍將失去!當(dāng)RabbitMQ退出或者崩潰,將會(huì)丟失隊(duì)列和消息。除非你不要隊(duì)列和消息。兩件事兒必須保證消息不被丟失:我們必須把“隊(duì)列”和“消息”設(shè)為持久化。
boolean durable = true;
channel.queueDeclare("hrabbit_queue_work", durable, false, false, null);
這里有一點(diǎn)需要注意的問題,我們直接把durable的false改成true就可以了嗎?因?yàn)槲椰F(xiàn)在運(yùn)行的程序中已經(jīng)存在了hrabbit_queue_work這個(gè)隊(duì)列,當(dāng)我再次執(zhí)行的時(shí)候,會(huì)拋出如下的異常
channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'hrabbit_queue_work'
盡管這行代碼是正確的,他不會(huì)運(yùn)行成功。因?yàn)槲覀円呀?jīng)定義了一個(gè)名叫hrabbit_queue_work的未持久化的隊(duì)列。RabbitMQ不允許使用不同的參數(shù)設(shè)定重新定義已經(jīng)存在的隊(duì)列,并且會(huì)返回一個(gè)錯(cuò)誤。 一個(gè)快速的解決方案——就是聲明一個(gè)不同名字的隊(duì)列,比如task_queue?;蛘呶覀兊卿浛刂婆_將隊(duì)列刪除就可以了。
系列文章:
RabbitMQ:RabbitMQ-理論基礎(chǔ)
RabbitMQ:快速入門hello word
RabbitMQ:RabbitMQ:work queues 工作隊(duì)列(Round-robin/Fair dispatch)
RabbitMQ:發(fā)布/訂閱 Publish/Subscribe
RabbitMQ:路由Routing
RabbitMQ:Topic類型的exchange
RabbitMQ:RabbitMQ之消息確認(rèn)機(jī)制(事務(wù)+Confirm)
RabbitMQ:spring整合RabbitMQ