自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

大白話設(shè)計(jì)RocketMQ延遲消息

開發(fā)
RocketMQ延遲消息的設(shè)計(jì)方式,是一種兼顧了性能和業(yè)務(wù)的優(yōu)秀設(shè)計(jì)。本文聊了RocketMQ延遲消息的使用、原理、解答了部分疑問。

延遲消息一般用于:提前發(fā)送消息,延遲一段時(shí)間后才需要被處理的場(chǎng)景。比如:下單半小時(shí)后還未支付,則取消訂單 釋放庫(kù)存 等。

RocketMQ的延遲消息使用上非常便捷,但是不支持任意時(shí)間的延遲,這一點(diǎn)對(duì)于有強(qiáng)迫癥的朋友來說就比較難受,但是搞明白為什么這么設(shè)計(jì)后,就自然釋懷了。

為什么RocketMQ不支持任意時(shí)間的延時(shí)?為什么延遲時(shí)間只能是從1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h這些時(shí)間段里選?如果讓你來設(shè)計(jì)RocketMQ的延遲消息,你會(huì)怎么設(shè)計(jì)?本文從以上幾個(gè)問題聊聊RocketMQ的延遲消息。

一、使用延遲消息

RocketMQ不支持任意時(shí)間的延遲,只有18個(gè)等級(jí)的延遲時(shí)間,默認(rèn)是:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h。從頭到尾共18個(gè)等級(jí)時(shí)間,s、m、h、d,分別表示秒、分、時(shí)、天。

默認(rèn)的18個(gè)等級(jí)對(duì)應(yīng)的時(shí)間可以修改,在broker.conf中增加如下配置,根據(jù)自身需求修改時(shí)間,然后重啟broker。

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

RocketMQ發(fā)送延遲消息只需要給消息設(shè)置延遲時(shí)間級(jí)別setDelayTimeLevel。

DefaultMQProducer producer = new DefaultMQProducer("TestProducerGroup");
Message rocketMsg = new Message(topic, tags, payloads);
// delayLevel=0時(shí),無(wú)需延遲
if (delayLevel > 0) {
    rocketMsg.setDelayTimeLevel(delayLevel);
}
SendResult sendResult = producer.send(rocketMsg, timeout);

二、延遲消息的原理

1.你會(huì)怎么設(shè)計(jì)

如果讓你來設(shè)計(jì)RocketMQ的延遲消息,你會(huì)怎么設(shè)計(jì)?筆者會(huì)這樣設(shè)計(jì):

  • 延遲消息也是個(gè)消息,只是多了延遲時(shí)間,既然是消息,不管是不是要立刻處理,先找個(gè)臨時(shí)Topic存儲(chǔ)起來。
  • Topic里面實(shí)際上是一個(gè)個(gè)隊(duì)列,那所有的延遲消息要存在一個(gè)隊(duì)列里嗎?不要放在同一個(gè)隊(duì)列里,因?yàn)橄⒏髯远加胁煌难舆t時(shí)間,如果放在一個(gè)隊(duì)列里,會(huì)牽扯到其余問題:比如排序、比如記錄消費(fèi)位置等。所以是按延遲時(shí)間分開存。
  • 消息已經(jīng)存起來了,那怎么處理呢?既然涉及到了延遲時(shí)間,那自然啟動(dòng)線程去定時(shí)獲取消息,判斷消息的延遲時(shí)間是否已經(jīng)到達(dá),到達(dá)之后則取出來投放到目的Topic。

2.粗略架構(gòu)圖

講到這里,延遲消息的架構(gòu)圖基本浮現(xiàn)出來了:

3.RocketMQ的設(shè)計(jì)

實(shí)際上RocketMQ在設(shè)計(jì)延遲消息時(shí),跟上面的思路基本類似,不在贅述,額外補(bǔ)充幾點(diǎn):

  • 消息進(jìn)入Broker后,會(huì)被存儲(chǔ)在TopicSCHEDULE_TOPIC_XXXX中,只是在Dashboard中看不到。
  • TopicSCHEDULE_TOPIC_XXXX中有18個(gè)消息隊(duì)列,分別存儲(chǔ)18個(gè)延遲等級(jí)對(duì)應(yīng)的消息。
  • RocketMQ 在啟動(dòng)時(shí),會(huì)從broker.conf中獲取18個(gè)等級(jí)對(duì)應(yīng)的時(shí)間,延遲等級(jí)和時(shí)間的關(guān)系會(huì)存在放到DelayLevelTable中。
  • RocketMQ會(huì)開啟18個(gè)定時(shí)任務(wù)每隔100ms,從TopicSCHEDULE_TOPIC_XXXX判斷18個(gè)隊(duì)列里的第一個(gè)消息是否可以被投放,如果可以投放,則在投放到原本的目的Topic。判斷邏輯:存入時(shí)間+延遲時(shí)間 > 當(dāng)前時(shí)間。

三、為什么不支持自定義延時(shí)時(shí)間

說到這里,估計(jì)你也能猜到,為什么不支持自定義延遲時(shí)間了,核心原因還是性能問題。

試想一下,如果設(shè)計(jì)成任意時(shí)間,那么就不可能使用18個(gè)隊(duì)列了,更不可能使用無(wú)限個(gè)隊(duì)列了,只可能使用單個(gè)隊(duì)列。

但是如果使用單個(gè)隊(duì)列,按照先進(jìn)先出的存放的話,那出現(xiàn)需要后進(jìn)先出的消息怎么辦?那只能對(duì)整個(gè)隊(duì)列進(jìn)行排序,如果消息量很大,每次有消息進(jìn)來都需要排序,那CPU肯定會(huì)被玩爆。

而且隊(duì)列里的消息被消費(fèi)后,都會(huì)記錄偏移量,如果每次有消息進(jìn)來都要排序,那偏移量則失去意義,增加了消息丟失的風(fēng)險(xiǎn)。

所以,RocketMQ的這種18個(gè)延遲時(shí)間等級(jí)的設(shè)計(jì),雖然在延遲時(shí)間的自由度上作出了妥協(xié),但是基本滿足業(yè)務(wù),性能也很優(yōu)秀。

四、總結(jié)

本文聊了RocketMQ延遲消息的使用、原理、解答了部分疑問。核心概念:臨時(shí)Topic、目的Topic、定時(shí)任務(wù)、18個(gè)延遲等級(jí)、18個(gè)消息隊(duì)列。RocketMQ延遲消息的設(shè)計(jì)方式,是一種兼顧了性能和業(yè)務(wù)的優(yōu)秀設(shè)計(jì)。

責(zé)任編輯:趙寧寧 來源: 不焦躁的程序員
相關(guān)推薦

2020-02-04 15:00:25

大白話認(rèn)識(shí)JVM

2023-12-18 10:08:56

2023-12-27 13:54:00

RocketMQJava架構(gòu)

2024-12-09 08:18:33

2020-02-20 11:32:09

Kafka概念問題

2019-05-17 08:27:23

SQL注入漏洞攻擊

2020-12-04 06:40:46

Zookeeper選舉機(jī)制

2021-03-01 18:38:32

Mock測(cè)試軟件

2019-08-14 09:13:38

中臺(tái)互聯(lián)網(wǎng)業(yè)務(wù)

2021-02-18 09:06:39

數(shù)據(jù)訪問者模式

2024-04-24 12:41:10

Rust安全性內(nèi)存

2023-09-18 14:34:07

Kubernetes云原生

2020-11-13 16:40:05

RocketMQ延遲消息架構(gòu)

2021-01-27 13:50:17

AI 數(shù)據(jù)機(jī)器學(xué)習(xí)

2018-11-19 08:34:22

Hadoop架構(gòu)HDFS

2020-09-08 06:30:59

微服務(wù)代碼模塊

2021-10-08 08:58:35

物聯(lián)網(wǎng)通信發(fā)布者

2023-05-06 07:29:49

Spring事務(wù)傳播

2023-09-13 09:02:22

PVPVC存儲(chǔ)

2020-11-10 16:00:55

機(jī)器學(xué)習(xí)人工智能AI
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)