怎么做購物網(wǎng)站到百度指數(shù)搜索榜
RabbitMQ中是可以實(shí)現(xiàn)延遲消息的,一般有兩種方式,分別是通過死信隊(duì)列以及通過延遲消息插件來實(shí)現(xiàn)。
擴(kuò)展:
死信隊(duì)列
當(dāng)rabbitMQ中的一條正常的消息,因?yàn)檫^了存活時(shí)間(TTL過期),隊(duì)列長度超限,被消費(fèi)者拒絕等原因無法被消費(fèi)時(shí),就會(huì)變成Dead Message ,即死信。
當(dāng)一個(gè)消息變成死信之后,他就能被重新發(fā)送到死信對(duì)列中(其實(shí)是交換機(jī)-exchange)。
那么基于這樣的機(jī)制,就可以實(shí)現(xiàn)延遲消息了。那就是我們給一個(gè)消息設(shè)定TTL ,但是并不消費(fèi)這個(gè)消息,等他過期,過期后就會(huì)進(jìn)入到死信隊(duì)列,然后我們?cè)俦O(jiān)聽死信隊(duì)列的消息就行了。
而且,rabbitMq中的這個(gè)ttl是可以設(shè)置任意時(shí)長的,這相比于RocketMQ只支持一些固定的時(shí)長而顯得更加靈活一些。
但是,死信隊(duì)列的實(shí)現(xiàn)方式存在一個(gè)問題,那就是可能造成隊(duì)頭阻塞,因?yàn)殛?duì)列是先進(jìn)先出的,而且每次只會(huì)判斷隊(duì)頭的消息是否過期,那么如果隊(duì)頭的消息時(shí)間很長,一直都不過期,那么就會(huì)阻塞整個(gè)隊(duì)列,這時(shí)候即便排在他后面的消息過期了,那么也會(huì)被一直阻塞。
基于RabbitMQ的死信隊(duì)列,可以實(shí)現(xiàn)延遲消息,非常靈活的實(shí)現(xiàn)定時(shí)關(guān)單,并且借助RabbitMQ的集群擴(kuò)展性,可以實(shí)現(xiàn)高可用,以及處理大并發(fā)。他的缺點(diǎn)第一是可能存在消息阻塞的問題,還有就是方案比較復(fù)雜,不僅要依賴RabbitMQ,而且還需要聲明很多隊(duì)列處理,增加系統(tǒng)的復(fù)雜度
RabbitMQ插件
其實(shí),基于RabbitMQ的話,可以不用死信隊(duì)列也能實(shí)現(xiàn)延遲消息,那就是基于? rabbitmq_delayed_message_exchange插件,這種方案能夠解決通過死信隊(duì)列實(shí)現(xiàn)延遲消息出現(xiàn)的消息阻塞問題,但是該插件從RabbitMQ的3.6.12開始支持的,所以有對(duì)版本有要求。
這個(gè)插件是官方出的,可以放心使用,安裝并啟用這個(gè)插件之后,就可以創(chuàng)建x-delayed-message類型的交換機(jī)了。
前面我們 提到的基于死信隊(duì)列的方式,是消息先回投遞到一個(gè)正常隊(duì)列,在ttl過期后進(jìn)入死信隊(duì)列,但是基于插件這種方式,消息并不會(huì)立即進(jìn)入隊(duì)列,而是先把他保存在一個(gè)基于erlang開發(fā)的mnesia數(shù)據(jù)庫中,然后通過一個(gè)定時(shí)器去查詢需要被投遞的消息,再把他們投遞到x-delayd-message交換機(jī)中。
基于rabbitmq插件的方式可以實(shí)現(xiàn)延遲消息,并且不存在消息阻塞的問題,但是因?yàn)槭腔诓寮?#xff0c;而這個(gè)插件支持的最大延遲時(shí)間是(2^32)-1毫秒,大約49天,超過這個(gè)時(shí)間會(huì)被立即消費(fèi)。
不過這個(gè)方案也有一定 限制,它將延遲消息存在于mbesia表中,并且在當(dāng)前節(jié)點(diǎn)上具有單個(gè)磁盤副本,存在丟失的問題。
目前該插件的當(dāng)前設(shè)計(jì)并不真正適合包含大量延遲消息(例如數(shù)十萬或者百萬)的場(chǎng)景,