在工作中想實(shí)現(xiàn)一個(gè)延遲功能,一般會(huì)借助rocketmq或者kafka的延遲隊(duì)列功能來實(shí)現(xiàn),但是這倆個(gè)消息中間件都有一個(gè)弊端,就是很難支持任意時(shí)間段的延遲,所以我想借助redis實(shí)現(xiàn)一個(gè)任意時(shí)間段的延遲功能
總體架構(gòu)圖

上述圖主要分為5個(gè)模塊
1 路由模塊,為了支持分布式部署,每接收一個(gè)延遲消息,都為這個(gè)消息生成一個(gè)全局唯一的消息ID,根據(jù)消息ID和路由算法,決定把延遲消息的消息ID加入到對(duì)應(yīng)的redis.sortSet隊(duì)列中
2 消息存儲(chǔ),所有的消息元數(shù)據(jù)存儲(chǔ)采用redis.hashmap結(jié)構(gòu),key為生成的全局消息ID(可以加一個(gè)前綴),value為消息的JSON格式,例如{"ttl":600,"topic":"XXX".......}
3 延遲隊(duì)列,所有的消息的延遲存儲(chǔ)在redis.sortSet中,sortSet中的每一個(gè)對(duì)象為全局生成的消息ID,score為到期時(shí)間時(shí)間戳
4 定時(shí)掃描timer,輪訓(xùn)redis.sortSet隊(duì)列,使用ZRANGEBYSCORE命令,獲取score小于等于當(dāng)前時(shí)間的所有消息ID,然后根據(jù)消息ID查詢r(jià)edis.hashmap中的消息元數(shù)據(jù),然后根據(jù)業(yè)務(wù)發(fā)送到對(duì)應(yīng)的topic下
5 消息中間件,借助消息中間件,訂閱者直接消費(fèi)消息,達(dá)到延遲的功能
總結(jié)
上述只是整體的羅列了一下借助redis怎么實(shí)現(xiàn)任意時(shí)間段延遲的功能,一些細(xì)節(jié)沒有詳細(xì)說明,如果想實(shí)現(xiàn)一個(gè)比較完美的延遲功能,需要考慮以下幾點(diǎn)
a 消息的發(fā)送失敗如果處理
b redis操作沒有事物保證
c 怎么保證hashmap和sortSet中的數(shù)據(jù)一致性
d 如果消息量大了怎么進(jìn)行動(dòng)態(tài)的擴(kuò)展