RocketMQ實(shí)戰(zhàn)(四)

前言

這將是RocketMQ實(shí)戰(zhàn)系列的最后一篇文章,該系列的文章列表如下:

《RocketMQ實(shí)戰(zhàn)(一)》

《RocketMQ實(shí)戰(zhàn)(二)》

《RocketMQ實(shí)戰(zhàn)(三):分布式事務(wù)》


RocketMQ 3.2.6的事務(wù)機(jī)制

在上一篇博客中,已經(jīng)知道RocketMQ 3.0.8是支持事務(wù)回查機(jī)制,但是在RocketMQ 3.2.6中取消了這個(gè)功能,下面我們繼續(xù)以轉(zhuǎn)賬功能分析我們自己如何解決這個(gè)問(wèn)題。


轉(zhuǎn)賬流程

在正常情況下,當(dāng)然沒(méi)有問(wèn)題,如果第五步(向MQ發(fā)送確認(rèn)消息)出現(xiàn)失敗,加上RocketMQ 3.2.6版本沒(méi)有事務(wù)回查機(jī)制,就會(huì)導(dǎo)致這條轉(zhuǎn)賬消息,在A銀行完成了操作,但是遲遲對(duì)B銀行系統(tǒng)不可見!


解決RocketMQ 3.2.6不支持事務(wù)回查的思路

用戶U1從A銀行系統(tǒng)轉(zhuǎn)賬給B銀行系統(tǒng)的用戶U2的處理過(guò)程如下:

第一步:A銀行系統(tǒng)生成一條轉(zhuǎn)賬消息,以事務(wù)消息的方式寫入RocketMQ,此時(shí)B銀行系統(tǒng)不可見這條消息

第二步:寫入MQ成功后,回調(diào)A銀行系統(tǒng),對(duì)T1,T2表進(jìn)行操作(很顯然需要是一個(gè)事務(wù))

我們重點(diǎn)關(guān)注下T2表,這個(gè)表是用來(lái)干嘛的呢?每條轉(zhuǎn)賬消息都會(huì)在T2表中,該表有2個(gè)特殊的字段:status,updatetime。(用途會(huì)在后文詳述)

第三步:完成第二步,接下來(lái)發(fā)送確認(rèn)消息給MQ,如果這個(gè)確認(rèn)消息發(fā)送成功,那么這條轉(zhuǎn)賬消息,將對(duì)B銀行系統(tǒng)可見。然后B銀行系統(tǒng),會(huì)在一個(gè)事務(wù)中完成對(duì)t3,t5的操作。

如果發(fā)送確認(rèn)消息給MQ失敗的處理思路:

首先,B銀行系統(tǒng),有一個(gè)定時(shí)任務(wù)(比如說(shuō)每隔1MIN執(zhí)行一次),掃描表t5,取得一段時(shí)間內(nèi)的數(shù)據(jù),發(fā)送給A銀行系統(tǒng)。要知道t5中的數(shù)據(jù),必然是A銀行系統(tǒng)成功處理并發(fā)送確認(rèn)消息成功的轉(zhuǎn)賬數(shù)據(jù)。為什么要發(fā)送給A銀行系統(tǒng)呢,其實(shí)就是為了找到那些發(fā)送確認(rèn)消息失敗的轉(zhuǎn)賬數(shù)據(jù)。那么怎么發(fā)給A銀行系統(tǒng)呢,這個(gè)方式比較多,可以考慮在來(lái)一個(gè)Topic,也可以考慮Netty等。發(fā)送給A銀行系統(tǒng),其實(shí)就是為了更新t2表的status,updatetime。

這里有一個(gè)關(guān)鍵,如何“掃描表t5,取得一段時(shí)間內(nèi)的數(shù)據(jù)”?這就是t4的作用,在t4中記錄一個(gè)time字段,每次定時(shí)任務(wù)啟動(dòng),先更新time(比如設(shè)定為當(dāng)前系統(tǒng)時(shí)間,設(shè)置前的的時(shí)間為old),然后掃描出t5中大于這個(gè)old時(shí)間的轉(zhuǎn)賬數(shù)據(jù),如此循環(huán)往復(fù)。

其次,A銀行系統(tǒng),也有一個(gè)定時(shí)任務(wù)(可以根據(jù)業(yè)務(wù)消費(fèi)能力定,可以大一些),掃描t2表(指定status及updatetime條件),將那些確認(rèn)消息發(fā)送失敗的轉(zhuǎn)賬消息找出來(lái),更新updatetime并發(fā)送給MQ。

這樣,我們并沒(méi)有改動(dòng)RocketMQ 3.2.6的源碼,而是在外圍解決了事務(wù)回查!

其實(shí)到這里,你可以發(fā)現(xiàn)RocketMQ的一個(gè)特點(diǎn),就是將生產(chǎn)者和MQ綁定,而不需要特別處理消費(fèi)者,這是為什么呢?因?yàn)橄⒅灰l(fā)往RocketMQ成功,那么就意味著成功,為什么這么說(shuō)?

前面,我們說(shuō)過(guò),消費(fèi)者端消費(fèi)消息只會(huì)產(chǎn)生2種錯(cuò)誤,第一:timeout,第二:exception。要知道RocketMQ對(duì)于超時(shí),會(huì)不斷重試;對(duì)于消費(fèi)異常,會(huì)根據(jù)消費(fèi)端的返回碼,會(huì)有重試機(jī)制保證。也就是,RocketMQ一定會(huì)讓消息得到消費(fèi),如果消費(fèi)有問(wèn)題,只能是消費(fèi)者的問(wèn)題,而不會(huì)是RocketMQ的問(wèn)題!


Pull Or Push

在前面的博客已經(jīng)提到,在RocketMQ中Consumer分為2類:Push Consumer、Pull Consumer。以前的例子都是Push Consumer,接下來(lái),為大家介紹下Pull Consumer。


通過(guò)MQPullConsumerScheduleService進(jìn)行操作


注冊(cè)回調(diào)并啟動(dòng)

從表面意思上來(lái)看,好像Push是MQ推送給消費(fèi)者,而Pull是消費(fèi)者從MQ中拉取;其實(shí)本質(zhì)上都是拉取模式PULL,即消費(fèi)者從MQ中輪詢?nèi)〉孟ⅰ?/b>

在Push模式下,Consumer把輪詢過(guò)程封裝了,并注冊(cè)了MessageListener監(jiān)聽器,取到消息后,喚醒MessageListener監(jiān)聽器中的consumeMessage()進(jìn)行消費(fèi),所以給我們?cè)斐闪烁杏X(jué)上好像是“推消息”。

在Pull模式下,需要特別注意的是,本質(zhì)上是從一個(gè)Topic下的所有Queue進(jìn)行拉取,而且每個(gè)Queue都必須記錄拉取位置,否則會(huì)導(dǎo)致重復(fù)消費(fèi)。還有拉取的時(shí)間間隔,拉取的大小等等。不過(guò)所有的這一切,MQPullConsumerScheduleService都替我們考慮清楚了,提供updateConsumeOffset去更新消費(fèi)的隊(duì)列的位置(默認(rèn)5S同步一次),提供setPullNextDelayTimeMillis設(shè)置下次拉取的時(shí)間間隔(應(yīng)該設(shè)置的大一些,至少大于5S)。

仔細(xì)回想下,對(duì)于Push方式的回調(diào) ? 和 ?Pull方式的回調(diào),還有什么關(guān)鍵區(qū)別么?

對(duì)于Push而言,不論是基于MessageListenerConcurrently的,還是基于MessageListenerOrderly的,都有返回值的;而Pull的doPullTask的返回值卻是void?

這意味,我們需要在pull方式中,注意自己處理每條消息消費(fèi)的異常情況!


運(yùn)行結(jié)果

通過(guò)運(yùn)行結(jié)果,可以印證上面的觀點(diǎn):為什么每次消費(fèi)都是4條開始,4條結(jié)束呢?因?yàn)橐粋€(gè)Topic下有4個(gè)Queue,而且上面的代碼實(shí)際上會(huì)針對(duì)每個(gè)Queue開啟一個(gè)線程去消費(fèi)!


RocketMQ Filter組件介紹

對(duì)于ActiveMQ而言,我們可以通過(guò)JMS Selectors機(jī)制(就是類似于SQL的語(yǔ)法)來(lái)實(shí)現(xiàn)過(guò)濾,很easy。那么和RocketMQ Filter組件有什么區(qū)別呢?

雖然,2者都能實(shí)現(xiàn)過(guò)濾,但是RocketMQ Filter的性能要更高效些,因?yàn)镽ocketMQ是在broker上將過(guò)濾后的數(shù)據(jù)發(fā)往filter,然后消費(fèi)者直接從filter上取得數(shù)據(jù);而ActiveMQ是消費(fèi)者直接在broker上進(jìn)行過(guò)濾消費(fèi)!(當(dāng)然,對(duì)于RocketMQ而言,Tag機(jī)制已經(jīng)足夠應(yīng)付日常絕大數(shù)的過(guò)濾功能,除非你的業(yè)務(wù)對(duì)性能有特別高的要求)


RocketMQ Filter機(jī)制

具體怎么做呢?這里我就不演示了,網(wǎng)上有很多例子,這里只說(shuō)下大致的過(guò)程:

第一:broker-xxx.properties中指定filter個(gè)數(shù)?

第二:上傳一段JAVA代碼,其實(shí)就是一個(gè)類


到這里,整個(gè)RocketMQ實(shí)戰(zhàn)系列就結(jié)束呢,你學(xué)到了么,體會(huì)到RocketMQ的強(qiáng)大了么?

See u next blog!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評(píng)論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評(píng)論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,368評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,235評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,427評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,656評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,160評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,380評(píng)論 2 379

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