Rocketmq-特性(1)

1 訂閱與發(fā)布

消息的發(fā)布是指某個生產(chǎn)者向某個topic發(fā)送消息厦酬;消息的訂閱是指某個消費(fèi)者關(guān)注了某個topic中帶有某些tag的消息,進(jìn)而從該topic消費(fèi)數(shù)據(jù)。

2 消息順序

消息有序指的是一類消息消費(fèi)時陪汽,能按照發(fā)送的順序來消費(fèi)。例如:一個訂單產(chǎn)生了三條消息分別是訂單創(chuàng)建褥蚯、訂單付款挚冤、訂單完成。消費(fèi)時要按照這個順序消費(fèi)才能有意義赞庶,但是同時訂單之間是可以并行消費(fèi)的训挡。RocketMQ可以嚴(yán)格的保證消息有序。

順序消息分為全局順序消息與分區(qū)順序消息歧强,全局順序是指某個Topic下的所有消息都要保證順序澜薄;部分順序消息只要保證每一組消息被順序消費(fèi)即可。

  • 全局順序 對于指定的一個 Topic摊册,所有消息按照嚴(yán)格的先入先出(FIFO)的順序進(jìn)行發(fā)布和消費(fèi)表悬。 適用場景:性能要求不高,所有的消息嚴(yán)格按照 FIFO 原則進(jìn)行消息發(fā)布和消費(fèi)的場景
  • 分區(qū)順序 對于指定的一個 Topic丧靡,所有消息根據(jù) sharding key 進(jìn)行區(qū)塊分區(qū)蟆沫。 同一個分區(qū)內(nèi)的消息按照嚴(yán)格的 FIFO 順序進(jìn)行發(fā)布和消費(fèi)籽暇。 Sharding key 是順序消息中用來區(qū)分不同分區(qū)的關(guān)鍵字段,和普通消息的 Key 是完全不同的概念饭庞。 適用場景:性能要求高戒悠,以 sharding key 作為分區(qū)字段,在同一個區(qū)塊中嚴(yán)格的按照 FIFO 原則進(jìn)行消息發(fā)布和消費(fèi)的場景舟山。

3 消息過濾

RocketMQ的消費(fèi)者可以根據(jù)Tag進(jìn)行消息過濾绸狐,也支持自定義屬性過濾。消息過濾目前是在Broker端實(shí)現(xiàn)的累盗,優(yōu)點(diǎn)是減少了對于Consumer無用消息的網(wǎng)絡(luò)傳輸寒矿,缺點(diǎn)是增加了Broker的負(fù)擔(dān)、而且實(shí)現(xiàn)相對復(fù)雜若债。

4 消息可靠性

RocketMQ支持消息的高可靠符相,影響消息可靠性的幾種情況:

  1. Broker非正常關(guān)閉
  2. Broker異常Crash
  3. OS Crash
  4. 機(jī)器掉電,但是能立即恢復(fù)供電情況
  5. 機(jī)器無法開機(jī)(可能是cpu蠢琳、主板啊终、內(nèi)存等關(guān)鍵設(shè)備損壞)
  6. 磁盤設(shè)備損壞

1)、2)傲须、3)蓝牲、4) 四種情況都屬于硬件資源可立即恢復(fù)情況,RocketMQ在這四種情況下能保證消息不丟泰讽,或者丟失少量數(shù)據(jù)(依賴刷盤方式是同步還是異步)例衍。

5)、6)屬于單點(diǎn)故障已卸,且無法恢復(fù)佛玄,一旦發(fā)生,在此單點(diǎn)上的消息全部丟失咬最。RocketMQ在這兩種情況下,通過異步復(fù)制欠动,可保證99%的消息不丟永乌,但是仍然會有極少量的消息可能丟失。通過同步雙寫技術(shù)可以完全避免單點(diǎn)具伍,同步雙寫勢必會影響性能翅雏,適合對消息可靠性要求極高的場合,例如與Money相關(guān)的應(yīng)用人芽。注:RocketMQ從3.0版本開始支持同步雙寫望几。

5 至少一次

至少一次(At least Once)指每個消息必須投遞一次。Consumer先Pull消息到本地萤厅,消費(fèi)完成后橄抹,才向服務(wù)器返回ack靴迫,如果沒有消費(fèi)一定不會ack消息,所以RocketMQ可以很好的支持此特性楼誓。

6 回溯消費(fèi)

回溯消費(fèi)是指Consumer已經(jīng)消費(fèi)成功的消息玉锌,由于業(yè)務(wù)上需求需要重新消費(fèi),要支持此功能疟羹,Broker在向Consumer投遞成功消息后主守,消息仍然需要保留。并且重新消費(fèi)一般是按照時間維度榄融,例如由于Consumer系統(tǒng)故障参淫,恢復(fù)后需要重新消費(fèi)1小時前的數(shù)據(jù),那么Broker要提供一種機(jī)制愧杯,可以按照時間維度來回退消費(fèi)進(jìn)度涎才。RocketMQ支持按照時間回溯消費(fèi),時間維度精確到毫秒民效。

7 事務(wù)消息

RocketMQ事務(wù)消息(Transactional Message)是指應(yīng)用本地事務(wù)和發(fā)送消息操作可以被定義到全局事務(wù)中憔维,要么同時成功,要么同時失敗畏邢。RocketMQ的事務(wù)消息提供類似 X/Open XA 的分布事務(wù)功能业扒,通過事務(wù)消息能達(dá)到分布式事務(wù)的最終一致。

8 定時消息

定時消息(延遲隊列)是指消息發(fā)送到broker后舒萎,不會立即被消費(fèi)程储,等待特定時間投遞給真正的topic。 broker有配置項(xiàng)messageDelayLevel臂寝,默認(rèn)值為“1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h”章鲤,18個level∨乇幔可以配置自定義messageDelayLevel败徊。注意,messageDelayLevel是broker的屬性掏缎,不屬于某個topic皱蹦。發(fā)消息時,設(shè)置delayLevel等級即可:msg.setDelayLevel(level)眷蜈。level有以下三種情況:

  • level == 0沪哺,消息為非延遲消息
  • 1<=level<=maxLevel,消息延遲特定時間酌儒,例如level==1辜妓,延遲1s
  • level > maxLevel,則level== maxLevel,例如level==20籍滴,延遲2h

定時消息會暫存在名為SCHEDULE_TOPIC_XXXX的topic中酪夷,并根據(jù)delayTimeLevel存入特定的queue,queueId = delayTimeLevel – 1异逐,即一個queue只存相同延遲的消息捶索,保證具有相同發(fā)送延遲的消息能夠順序消費(fèi)。broker會調(diào)度地消費(fèi)SCHEDULE_TOPIC_XXXX灰瞻,將消息寫入真實(shí)的topic腥例。

需要注意的是,定時消息會在第一次寫入和調(diào)度寫入真實(shí)topic時都會計數(shù)酝润,因此發(fā)送數(shù)量燎竖、tps都會變高。

9 消息重試

Consumer消費(fèi)消息失敗后要销,要提供一種重試機(jī)制构回,令消息再消費(fèi)一次。Consumer消費(fèi)消息失敗通呈韪溃可以認(rèn)為有以下幾種情況:

  • 由于消息本身的原因纤掸,例如反序列化失敗,消息數(shù)據(jù)本身無法處理(例如話費(fèi)充值浑塞,當(dāng)前消息的手機(jī)號被注銷借跪,無法充值)等。這種錯誤通常需要跳過這條消息酌壕,再消費(fèi)其它消息掏愁,而這條失敗的消息即使立刻重試消費(fèi),99%也不成功卵牍,所以最好提供一種定時重試機(jī)制果港,即過10秒后再重試。
  • 由于依賴的下游應(yīng)用服務(wù)不可用糊昙,例如db連接不可用辛掠,外系統(tǒng)網(wǎng)絡(luò)不可達(dá)等。遇到這種錯誤释牺,即使跳過當(dāng)前失敗的消息萝衩,消費(fèi)其他消息同樣也會報錯。這種情況建議應(yīng)用sleep 30s船侧,再消費(fèi)下一條消息欠气,這樣可以減輕Broker重試消息的壓力厅各。

RocketMQ會為每個消費(fèi)組都設(shè)置一個Topic名稱為“%RETRY%+consumerGroup”的重試隊列(這里需要注意的是镜撩,這個Topic的重試隊列是針對消費(fèi)組,而不是針對每個Topic設(shè)置的),用于暫時保存因?yàn)楦鞣N異常而導(dǎo)致Consumer端無法消費(fèi)的消息袁梗∫搜欤考慮到異常恢復(fù)起來需要一些時間遮怜,會為重試隊列設(shè)置多個重試級別淋袖,每個重試級別都有與之對應(yīng)的重新投遞延時,重試次數(shù)越多投遞延時就越大锯梁。RocketMQ對于重試消息的處理是先保存至Topic名稱為“SCHEDULE_TOPIC_XXXX”的延遲隊列中即碗,后臺定時任務(wù)按照對應(yīng)的時間進(jìn)行Delay后重新保存至“%RETRY%+consumerGroup”的重試隊列中。

10 消息重投

生產(chǎn)者在發(fā)送消息時陌凳,同步消息失敗會重投剥懒,異步消息有重試,oneway沒有任何保證合敦。消息重投保證消息盡可能發(fā)送成功初橘、不丟失充岛,但可能會造成消息重復(fù)崔梗,消息重復(fù)在RocketMQ中是無法避免的問題炒俱。消息重復(fù)在一般情況下不會發(fā)生权悟,當(dāng)出現(xiàn)消息量大峦阁、網(wǎng)絡(luò)抖動驹闰,消息重復(fù)就會是大概率事件撒会。另外诵肛,生產(chǎn)者主動重發(fā)、consumer負(fù)載變化也會導(dǎo)致重復(fù)消息蓄诽。如下方法可以設(shè)置消息重試策略:

  • retryTimesWhenSendFailed:同步發(fā)送失敗重投次數(shù),默認(rèn)為2锯岖,因此生產(chǎn)者會最多嘗試發(fā)送retryTimesWhenSendFailed + 1次嚎莉。不會選擇上次失敗的broker趋箩,嘗試向其他broker發(fā)送,最大程度保證消息不丟竹勉。超過重投次數(shù)次乓,拋出異常,由客戶端保證消息不丟杏慰。當(dāng)出現(xiàn)RemotingException缘滥、MQClientException和部分MQBrokerException時會重投朝扼。
  • retryTimesWhenSendAsyncFailed:異步發(fā)送失敗重試次數(shù)凹耙,異步重試不會選擇其他broker,僅在同一個broker上做重試柏卤,不保證消息不丟。
  • retryAnotherBrokerWhenNotStoreOK:消息刷盤(主或備)超時或slave不可用(返回狀態(tài)非SEND_OK),是否嘗試發(fā)送到其他broker,默認(rèn)false每篷。十分重要消息可以開啟。

11 流量控制

生產(chǎn)者流控矗晃,因?yàn)閎roker處理能力達(dá)到瓶頸;消費(fèi)者流控俗他,因?yàn)橄M(fèi)能力達(dá)到瓶頸拯辙。

生產(chǎn)者流控:

  • commitLog文件被鎖時間超過osPageCacheBusyTimeOutMills時,參數(shù)默認(rèn)為1000ms夕春,返回流控片排。
  • 如果開啟transientStorePoolEnable == true率寡,且broker為異步刷盤的主機(jī),且transientStorePool中資源不足捅僵,拒絕當(dāng)前send請求,返回流控馒闷。
  • broker每隔10ms檢查send請求隊列頭部請求的等待時間,如果超過waitTimeMillsInSendQueue塞祈,默認(rèn)200ms,拒絕當(dāng)前send請求斯议,返回流控焊唬。
  • broker通過拒絕send 請求方式實(shí)現(xiàn)流量控制赶促。

注意谤祖,生產(chǎn)者流控粥喜,不會嘗試消息重投额湘。

消費(fèi)者流控:

  • 消費(fèi)者本地緩存消息數(shù)超過pullThresholdForQueue時鬓梅,默認(rèn)1000紧阔。
  • 消費(fèi)者本地緩存消息大小超過pullThresholdSizeForQueue時坊罢,默認(rèn)100MB。
  • 消費(fèi)者本地緩存消息跨度超過consumeConcurrentlyMaxSpan時擅耽,默認(rèn)2000活孩。

消費(fèi)者流控的結(jié)果是降低拉取頻率。

12 死信隊列

死信隊列用于處理無法被正常消費(fèi)的消息乖仇。當(dāng)一條消息初次消費(fèi)失敗憾儒,消息隊列會自動進(jìn)行消息重試;達(dá)到最大重試次數(shù)后乃沙,若消費(fèi)依然失敗起趾,則表明消費(fèi)者在正常情況下無法正確地消費(fèi)該消息,此時警儒,消息隊列 不會立刻將消息丟棄训裆,而是將其發(fā)送到該消費(fèi)者對應(yīng)的特殊隊列中。

RocketMQ將這種正常情況下無法被消費(fèi)的消息稱為死信消息(Dead-Letter Message)蜀铲,將存儲死信消息的特殊隊列稱為死信隊列(Dead-Letter Queue)边琉。在RocketMQ中,可以通過使用console控制臺對死信隊列中的消息進(jìn)行重發(fā)來使得消費(fèi)者實(shí)例再次進(jìn)行消費(fèi)记劝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艺骂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子隆夯,更是在濱河造成了極大的恐慌钳恕,老刑警劉巖别伏,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異忧额,居然都是意外死亡厘肮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門睦番,熙熙樓的掌柜王于貴愁眉苦臉地迎上來类茂,“玉大人,你說我怎么就攤上這事托嚣」欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵示启,是天一觀的道長兢哭。 經(jīng)常有香客問我,道長夫嗓,這世上最難降的妖魔是什么迟螺? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮舍咖,結(jié)果婚禮上矩父,老公的妹妹穿的比我還像新娘。我一直安慰自己排霉,他們只是感情好窍株,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著攻柠,像睡著了一般夹姥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辙诞,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天辙售,我揣著相機(jī)與錄音,去河邊找鬼飞涂。 笑死旦部,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的较店。 我是一名探鬼主播士八,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼梁呈!你這毒婦竟也來了婚度?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤官卡,失蹤者是張志新(化名)和其女友劉穎蝗茁,沒想到半個月后醋虏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哮翘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年颈嚼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饭寺。...
    茶點(diǎn)故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡阻课,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艰匙,到底是詐尸還是另有隱情限煞,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布员凝,位于F島的核電站署驻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绊序。R本人自食惡果不足惜硕舆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一秽荞、第九天 我趴在偏房一處隱蔽的房頂上張望骤公。 院中可真熱鬧,春花似錦扬跋、人聲如沸阶捆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洒试。三九已至,卻和暖如春朴上,著一層夾襖步出監(jiān)牢的瞬間垒棋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工痪宰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叼架,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓衣撬,卻偏偏與公主長得像乖订,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子具练,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評論 2 355

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