RabbitMQ實(shí)現(xiàn)延時(shí)隊(duì)列

接之前分享過(guò)的文章【RabbitMQ的死信隊(duì)列和延時(shí)隊(duì)列】觉至,更詳細(xì)的聊一下RabbitMQ延時(shí)隊(duì)列裆蒸。

在RabbitMQ中本身是不存在延時(shí)隊(duì)列冬殃,如果需要使用RabbitMQ來(lái)實(shí)現(xiàn)延時(shí)隊(duì)列,有兩種方式:

  • 第一種:DLX+TTL(Time To Live);
    設(shè)置TTL分為兩種:在隊(duì)列屬性中設(shè)置TTL白指,在消息屬性中設(shè)置TTL
  • 第二種:使用延時(shí)消息插件浙芙;

1. DLX+TTL模擬延時(shí)隊(duì)列

通過(guò)過(guò)期消息和死信隊(duì)列來(lái)模擬出延時(shí)隊(duì)列,消費(fèi)者監(jiān)聽(tīng)死信交換器綁定的隊(duì)列卢厂,而不要監(jiān)聽(tīng)消息發(fā)送的隊(duì)列,這樣就可以模擬出延時(shí)隊(duì)列了惠啄。

通過(guò)過(guò)期消息和死信隊(duì)列來(lái)模擬出延時(shí)隊(duì)列:

前面講了過(guò)期消息有兩種實(shí)現(xiàn)方法慎恒,第一種是通過(guò)對(duì)隊(duì)列進(jìn)行設(shè)置,第二種是通過(guò)對(duì)消息本身進(jìn)行設(shè)置撵渡。

第一種方法通過(guò)隊(duì)列設(shè)置融柬,需要在隊(duì)列聲明的時(shí)候設(shè)置才有效。而如果使用這種方法姥闭,那么每增加一個(gè)新的時(shí)間需求丹鸿,就要增加一個(gè)隊(duì)列,顯然這種方法不夠靈活棚品。

既然第一種方法不夠靈活靠欢,那么咱通過(guò)第二種方法就可以實(shí)現(xiàn)靈活性。然而事情并沒(méi)有那么簡(jiǎn)單铜跑,因?yàn)榍懊嬉呀?jīng)講了门怪,如果使用在消息屬性上設(shè)置TTL的方式,消息可能并不會(huì)按時(shí)“死亡“锅纺。

因?yàn)镽abbitMQ只會(huì)檢查隊(duì)列頭部的消息是否過(guò)期掷空,如果過(guò)期則丟到死信隊(duì)列,所以如果隊(duì)列中第一個(gè)消息的延時(shí)時(shí)長(zhǎng)很長(zhǎng)囤锉,而第二個(gè)消息的延時(shí)時(shí)長(zhǎng)很短坦弟,則第二個(gè)消息并不會(huì)優(yōu)先得到執(zhí)行。

所以不管是在消息維度或是隊(duì)列維度設(shè)置過(guò)期時(shí)間綁定死信隊(duì)列模擬延時(shí)隊(duì)列官地,歸根結(jié)底都是在隊(duì)列上實(shí)現(xiàn)消息的延遲酿傍,這樣方式存在不靈活或者不及時(shí)的時(shí)序問(wèn)題。

而使用延時(shí)消息插件驱入,是自定義交換機(jī)赤炒,讓交換機(jī)擁有了延遲發(fā)送消息的能力,從而實(shí)現(xiàn)消息的精準(zhǔn)延時(shí)亏较。下面就簡(jiǎn)單介紹一下莺褒。

2. 使用延時(shí)消息插件

使用延時(shí)消息插件需要安裝延時(shí)消息插件( rabbitmq-delayed-message-exchange),我們可以聲明 x-delayed-message 類型的 Exchange雪情,消息發(fā)送時(shí)指定消息頭 x-delay 以毫秒為單位將消息進(jìn)行延遲投遞遵岩。

實(shí)現(xiàn)原理:

使用DLX+TTL的模式,消息首先會(huì)路由到一個(gè)正常的隊(duì)列巡通,然后根據(jù)設(shè)置的TTL進(jìn)入死信隊(duì)列尘执,與之不同的是通過(guò) x-delayed-message 聲明的交換機(jī),它的消息在發(fā)布之后不會(huì)立即進(jìn)入隊(duì)列扁达,而先將消息保存至 Mnesia(一個(gè)分布式數(shù)據(jù)庫(kù)管理系統(tǒng)正卧,適合于電信和其它需要持續(xù)運(yùn)行和具備軟實(shí)時(shí)特性的 Erlang 應(yīng)用。目前資料介紹的不是很多)

這個(gè)插件將會(huì)嘗試確認(rèn)消息是否過(guò)期跪解,首先要確保消息的延遲范圍是 Delay > 0, Delay =< ?ERL_MAX_T(在 Erlang 中可以被設(shè)置的范圍為 (2^32)-1 毫秒)炉旷,如果消息過(guò)期通過(guò) x-delayed-type 類型標(biāo)記的交換機(jī)投遞至目標(biāo)隊(duì)列,整個(gè)消息的投遞過(guò)程也就完成了叉讥。


總結(jié)一下窘行,可以看得出來(lái),通過(guò)過(guò)期消息和死信隊(duì)列雖然可以模擬延時(shí)隊(duì)列图仓,但還需要?jiǎng)?chuàng)建兩個(gè)交換機(jī)(死信隊(duì)列交換機(jī)+處理隊(duì)列交換機(jī))罐盔、兩個(gè)隊(duì)列(死信隊(duì)列+處理隊(duì)列),更何況無(wú)法達(dá)到一個(gè)靈活通用的延遲隊(duì)列救崔。而使用rabbitmq的延時(shí)消息插件方式惶看,只需要?jiǎng)?chuàng)建一個(gè)交換機(jī)和一個(gè)隊(duì)列捏顺,就可以做到延時(shí)靈活,明顯這種方式使用起來(lái)更簡(jiǎn)單纬黎、更靈活通用幅骄。

局限性:

延時(shí)消息插件實(shí)現(xiàn)RabbitMQ延時(shí)隊(duì)列這種方式也不完全是一個(gè)銀彈,它將延遲消息存在于Mnesia表中本今,并且在當(dāng)前節(jié)點(diǎn)上具有單個(gè)磁盤副本拆座,它們將在節(jié)點(diǎn)重啟之后幸存。

目前該插件的當(dāng)前設(shè)計(jì)并不真正適合包含大量延遲消息(例如數(shù)十萬(wàn)或數(shù)百萬(wàn))的場(chǎng)景冠息,詳情參見(jiàn) #/issues/72 另外該插件的一個(gè)可變性來(lái)源是依賴于 Erlang 計(jì)時(shí)器挪凑,在系統(tǒng)中使用了一定數(shù)量的長(zhǎng)時(shí)間計(jì)時(shí)器之后,它們開(kāi)始爭(zhēng)用調(diào)度程序資源逛艰,并且時(shí)間漂移不斷累積躏碳。

插件的禁用要慎重,以下方式可以實(shí)現(xiàn)將插件禁用瓮孙,但是注意如果此時(shí)還有延遲消息未消費(fèi)唐断,那么禁掉此插件后所有的未消費(fèi)的延遲消息將丟失。

rabbitmq-plugins disable rabbitmq_delayed_message_exchange

如果你采用了 Delayed Message 插件這種方式來(lái)實(shí)現(xiàn)杭抠,對(duì)于消息可用性要求較高的脸甘,在發(fā)現(xiàn)消息之前可以先落入 DB 打標(biāo)記,消費(fèi)之后將消息標(biāo)記為已消費(fèi)偏灿,中間可以加入定時(shí)任務(wù)做檢測(cè)丹诀,這可以進(jìn)一步保證你的消息的可靠性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翁垂,一起剝皮案震驚了整個(gè)濱河市铆遭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沿猜,老刑警劉巖枚荣,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啼肩,居然都是意外死亡橄妆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門祈坠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)害碾,“玉大人,你說(shuō)我怎么就攤上這事赦拘』潘妫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阁猜。 經(jīng)常有香客問(wèn)我丸逸,道長(zhǎng),這世上最難降的妖魔是什么蹦漠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任椭员,我火速辦了婚禮车海,結(jié)果婚禮上笛园,老公的妹妹穿的比我還像新娘。我一直安慰自己侍芝,他們只是感情好研铆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著州叠,像睡著了一般棵红。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咧栗,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天逆甜,我揣著相機(jī)與錄音,去河邊找鬼致板。 笑死交煞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斟或。 我是一名探鬼主播素征,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼萝挤!你這毒婦竟也來(lái)了御毅?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怜珍,失蹤者是張志新(化名)和其女友劉穎端蛆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體酥泛,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡今豆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了揭璃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晚凿。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瘦馍,靈堂內(nèi)的尸體忽然破棺而出歼秽,到底是詐尸還是另有隱情,我是刑警寧澤情组,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布燥筷,位于F島的核電站箩祥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肆氓。R本人自食惡果不足惜袍祖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谢揪。 院中可真熱鬧蕉陋,春花似錦、人聲如沸拨扶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)患民。三九已至缩举,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匹颤,已是汗流浹背仅孩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留印蓖,地道東北人辽慕。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像另伍,于是被迫代替她去往敵國(guó)和親鼻百。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容