延時隊(duì)列實(shí)現(xiàn)方法列表

1、JDK提供的DelayQueue

一種支持延時獲取元素的無界阻塞隊(duì)列。

內(nèi)部持有一個PriorityQueue,每個對象都被放入了這個隊(duì)列,隊(duì)列中的對象按照優(yōu)先級進(jìn)行了排序,隊(duì)列頭部是最先會超時的對象。

take方法會一直阻塞,直到隊(duì)列頭部的對象超時后才可以被取出。

2、Redis sorted set(ZSET)

實(shí)現(xiàn)思路大同小異。以過期時間的時間戳作為score。

生產(chǎn)者將消息內(nèi)容作為member,時間戳作為score調(diào)用ZADD來生產(chǎn)消息;

消費(fèi)者用ZRANGEBYSCORE命令獲取N秒之前的數(shù)據(jù)進(jìn)行輪詢處理,使用min和max向前推N秒來卡延時的消息。

3、RabbitMQ

rabbitMQ中可以對Message設(shè)置 x-message-ttl(TTL = Time To Live)來控制消息的生存時間。超時以后消息變?yōu)閐ead letter(死信)。

同時,RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可選)兩個參數(shù),如果隊(duì)列內(nèi)出現(xiàn)了dead letter,則按照這兩個參數(shù)重新路由轉(zhuǎn)發(fā)到指定的隊(duì)列。

利用這樣的特性,設(shè)置兩個隊(duì)列,A隊(duì)列無消費(fèi)者,生產(chǎn)者向該隊(duì)列發(fā)送消息,消息設(shè)定TTL;同時設(shè)定A中出現(xiàn)死信以后將消息轉(zhuǎn)發(fā)到B隊(duì)列;B隊(duì)列使用正常設(shè)定即可,所有消費(fèi)者從B讀取消息。

即可完成延時時間為TTL的延時隊(duì)列。

4、Redis 過期回調(diào)

在Redis中開啟監(jiān)聽key是否過期的事件,一旦key過期會觸發(fā)一個callback事件。

有點(diǎn)類似MQ的隊(duì)列事件監(jiān)聽。

5、Kafka

Kafka有專門用于實(shí)現(xiàn)延遲功能的定時器(SystemTimer)。底層使用的是時間輪(TimingWheel)模型(環(huán)形隊(duì)列,下面掛接雙向鏈表)。

操作效率非常高。JDK的DelayQueue插入和刪除操作的平均時間復(fù)雜度為O(nlog(n)),而Kafka基于時間輪可以將插入和刪除操作的時間復(fù)雜度都降為O(1)。

6、Netty等同樣實(shí)現(xiàn)了時間輪的中間件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容