如何優(yōu)雅的使用MQ-詳述功能場景

消息隊列(MQ)是一種不同應(yīng)用程序之間(跨進程)的通信方法。應(yīng)用程序通過寫入和檢索出入列隊的數(shù)據(jù)(消息)來通信绪穆,而無需通過專用連接來鏈接它們陆馁。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進行通信,而不是通過直接調(diào)用彼此來通信芋忿,直接調(diào)用通常是用于諸如遠程過程調(diào)用(Remote Procedure Call. RPC)的技術(shù)烫止。排隊指的是應(yīng)用程序通過隊列來通信蒋荚。隊列的使用除去了接收和發(fā)送應(yīng)用程序同時執(zhí)行的要求。這樣天然的就實現(xiàn)了異步的目標(biāo)馆蠕。那么MQ還有哪些功能場景呢期升。下面逐一介紹。

解耦

解耦.png

MQ最直接的使用場景就是可以將兩個系統(tǒng)進行解耦互躬,比如我們的貨款抵扣業(yè)務(wù)場景播赁,用戶生成訂單發(fā)送MQ后立即返回,結(jié)算系統(tǒng)去消費該MQ進行用戶賬戶金額的扣款吼渡。這樣訂單系統(tǒng)只需要關(guān)注把訂單創(chuàng)建成功容为,最大可能的提高訂單量,并且生成訂單后立即返回用戶寺酪。而結(jié)算系統(tǒng)重點關(guān)心的是賬戶金額的扣減坎背,保證賬戶金額最終一致。這個場景里面還會涉及到重試冪等性問題寄雀,后面有介紹得滤。

削峰填谷

還是以訂單系統(tǒng)和結(jié)算系統(tǒng)場景為例,如果訂單系統(tǒng)通過RPC框架來調(diào)用結(jié)算系統(tǒng)盒犹,在有高峰促銷的情況下生成訂單的量會非常大懂更,而且由于生成訂單的速度也非痴R担快,這樣勢必會給結(jié)算系統(tǒng)造成系統(tǒng)壓力沮协,服務(wù)器利用率則會偏高坛猪,但在不是高峰的時間點訂單量比較小,結(jié)算系統(tǒng)的服務(wù)器利用率則會偏低皂股。對于結(jié)算系統(tǒng)來說就會出現(xiàn)下面這樣的高峰波谷現(xiàn)象圖。

削峰填谷.png

那么如果通過MQ的方式命黔,將訂單存儲到MQ隊列中呜呐,消費端通過拉取的方式,并且拉去速度有消費端來控制悍募,則就可以控制流量趨于平穩(wěn)蘑辑。這樣對于結(jié)算系統(tǒng)來講,就達到了削峰填谷的目的坠宴⊙蠡辏或者說起到了流控的目標(biāo)。接下來喜鼓,我們介紹一下拉取方式副砍。

拉取模式指用戶在代碼里主動調(diào)用pull方法,不需要在配置文件里面再配置<mq:listener />庄岖,拉取的速度由用戶控制豁翎,調(diào)用一次拉取一次消息進行消費,這里要重視消費的速度如果消費性能下降一定會造成積壓隅忿,因此用戶自己啟用多線程控制并行度以提高消費速度心剥。
代碼樣例:

messageConsumer.start();
for (;;){
    //手動拉取消息
    messageConsumer.pull(topic,messageListener);
}

method: pull(String topic,MessageListener listener)
topic:指消費的主題名
listener:是一個回調(diào)對象,當(dāng)pull拉取到消息后會主動調(diào)用listener.onMessage()背桐,
與監(jiān)聽模式的區(qū)別是:監(jiān)聽模式由MQ客戶端守護線程去不停的拉取消息進行消費优烧,拉取模式由用戶控制拉取的頻率,不主動調(diào)用就不會消費消息链峭。但是都不需要主動對消息進行確認(rèn)畦娄。這種方式更適合寫場景,保證最終結(jié)果落地即可熏版,因為讀是需要立即返回以免讓用戶長時間等待從而影響用戶體驗纷责。

最終一致性

最終一致性.png

一致性問題分為強一致性、弱一致性撼短、最終一致性再膳。大多數(shù)互聯(lián)網(wǎng)業(yè)務(wù)要求實現(xiàn)最終一致性。還是以訂單系統(tǒng)和結(jié)算系統(tǒng)業(yè)務(wù)場景舉例曲横,訂單系統(tǒng)創(chuàng)建成功一個訂單后給用戶返回的結(jié)果即是成功并明確告訴用戶會從賬戶中扣除相應(yīng)的金額喂柒。那么結(jié)算系統(tǒng)需要保持跟訂單系統(tǒng)相同的狀態(tài)即從用賬戶中實際扣除一致的金額不瓶。訂單系統(tǒng)會涉及兩個動作,一個是創(chuàng)建成功訂單灾杰,一個是發(fā)送成功通知到MQ蚊丐,我們就可以把這兩個動作放入到一個本地事務(wù)中,要么成功要么失敗艳吠。當(dāng)一次發(fā)送MQ失敗之后麦备,可以結(jié)合定時任務(wù)進行補償,這樣可以保證生成訂單的結(jié)果可以落地到mq的存儲中昭娩。同樣結(jié)算系統(tǒng)消費端依靠MQ重試機制一直發(fā)送消息凛篙,直到消費端最終確認(rèn)扣款業(yè)務(wù)成功處理完成。這樣我們通過消息落地加補償栏渺,消費端從業(yè)務(wù)上面考慮重復(fù)消費的保障呛梆,也就是做好冪等性操作,利用MQ實現(xiàn)了最終一致性磕诊。

廣播消費

MQ有兩種消息模式一種是點對點模式填物,一種是發(fā)布/訂閱模式(最常用的模式)。同時發(fā)布/訂閱模式按照消費類型又可以分為集群消費和廣播消費霎终。大部分情況下我們使用的是集群消費滞磺。

集群消費:MQ發(fā)送任何一條消息,集群中只有一臺服務(wù)器可隨機消費到這條消息神僵。如下圖:

集群消費.png

廣播消費:MQ發(fā)送每一條消息雁刷,集群中的每一臺服務(wù)器至少消費到一次。如下圖:

廣播消費.png

廣播消費舉例:消息推送系統(tǒng)保礼。首先某一個客戶端與消息中心應(yīng)用集群中的一臺服務(wù)器建立長連接并將連接session信息保存到當(dāng)前服務(wù)器內(nèi)存中沛励,集群在消費業(yè)務(wù)消息的時候,是不知道該客戶端建立的長連接在哪一臺服務(wù)器上面炮障。這個時候通過廣播消費目派,集群中的每一臺服務(wù)器都可以消費到業(yè)務(wù)消息。在決定向用戶推送通知之前會判斷當(dāng)前服務(wù)器內(nèi)存中是否有該客戶端的連接session信息胁赢,如果有則推送企蹭,進而客戶端通過http協(xié)議拉取用戶的消息實體。如果session信息不在當(dāng)前服務(wù)器上面智末,則丟棄谅摄。如下圖:

廣播消費舉例.png

廣播消費注意事項:
1、消費進度在消費端管理系馆,比如默認(rèn)會在主目錄下創(chuàng)建offset文件夾送漠,偏移量文件存儲在offset目錄下,出現(xiàn)重復(fù)的概率要大于集群消費由蘑。
2闽寡、MQ可以確保每條消息至少被每臺消費方服務(wù)器消費一次代兵,但是如果消費方消費失敗,不會進入重試爷狈,因此業(yè)務(wù)方需要關(guān)注消費失敗的情況植影。
3、由于廣播消費消息不會進行確認(rèn)涎永,所以管理端上顯示的積壓數(shù)會一直不變思币,需要以出對數(shù)為準(zhǔn)。

使用集群消費模擬廣播

在發(fā)布/訂閱模式中羡微,如果是集群消費支救,那么一條消息只能被集群中的隨機一臺服務(wù)器消費到,如果我們有需要集群中的每臺服務(wù)器消費到比如上面的消息推送的例子拷淘,我們使用廣播消費來實現(xiàn)。但是廣播消費有一些弊端比如不支持順序消息指孤,消費進度在客戶端維護出現(xiàn)重復(fù)的幾率要大于集群模式启涯,廣播模式下不能維護消費進度所以管理端上面的積壓數(shù)一直保持不變,我們就必須以出隊數(shù)為準(zhǔn)恃轩,也就是不能夠支持消息堆積的查詢结洼。如果要規(guī)避這些弊端,那么我們可以利用集群消費來模擬廣播叉跛,在集群消費中松忍,我們的每臺服務(wù)器上面的消費APPID是相同的,如果要達到廣播的效果筷厘,那么每臺服務(wù)器上面的消費APPID保持不同就可以了鸣峭。

模擬廣播.png

重試之坑

重試之坑.png

MQ的重試功能可以保證數(shù)據(jù)結(jié)果最終得到處理,但同時也正因為有重試那么在業(yè)務(wù)處理的時候就需要格外注意冪等性的問題酥艳。比如貨款抵扣業(yè)務(wù)摊溶,訂單系統(tǒng)生成訂單之后調(diào)用結(jié)算平臺去扣除用戶的賬戶金額。結(jié)算平臺要根據(jù)流水號去計算充石,如果訂單系統(tǒng)在調(diào)用結(jié)算平臺的時候發(fā)生了網(wǎng)絡(luò)異常莫换,造成了結(jié)算平臺實際上已經(jīng)得到請求并且已處理。訂單系統(tǒng)一側(cè)認(rèn)為發(fā)生異常需要重試骤铃,后續(xù)再發(fā)送到結(jié)算平臺的訂單就會造成重復(fù)扣款問題拉岁。所以流水號尤其要注意需要保證重試過程中每次發(fā)送的流水號是一致的,結(jié)算平臺會根據(jù)流水號去做業(yè)務(wù)校驗惰爬,如果已經(jīng)處理喊暖,則丟棄,最終確保冪等性补鼻。

總結(jié)

我們介紹了MQ常見的使用場景哄啄,以及每種場景下的使用注意事項雅任。尤其是在重試功能中,重試本來是MQ提供的一種保持?jǐn)?shù)據(jù)最終可以得到確認(rèn)的方法咨跌,但是如果業(yè)務(wù)使用上面不注意冪等性沪么,則會帶來業(yè)務(wù)數(shù)據(jù)的不一致甚至像重復(fù)扣款這樣比較嚴(yán)重的后果。我們還介紹了發(fā)布/訂閱模式下的廣播消費的使用舉例锌半,也介紹了它的缺點以及可以使用集群消費來模擬廣播禽车。鑒于以上每種場景都給我們提供了很好的說明使得大家在以后使用MQ的過程中可以更好的發(fā)揮MQ的強大作用。

版權(quán)聲明 轉(zhuǎn)載請標(biāo)明作者和出處

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刊殉,一起剝皮案震驚了整個濱河市殉摔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌记焊,老刑警劉巖逸月,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異遍膜,居然都是意外死亡碗硬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門瓢颅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩尾,“玉大人,你說我怎么就攤上這事挽懦『惨猓” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵信柿,是天一觀的道長冀偶。 經(jīng)常有香客問我,道長渔嚷,這世上最難降的妖魔是什么蔫磨? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮圃伶,結(jié)果婚禮上堤如,老公的妹妹穿的比我還像新娘。我一直安慰自己窒朋,他們只是感情好搀罢,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侥猩,像睡著了一般榔至。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欺劳,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天唧取,我揣著相機與錄音铅鲤,去河邊找鬼。 笑死枫弟,一個胖子當(dāng)著我的面吹牛邢享,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播淡诗,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼骇塘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了韩容?” 一聲冷哼從身側(cè)響起款违,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎群凶,沒想到半個月后插爹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡请梢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年递惋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溢陪。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖睛廊,靈堂內(nèi)的尸體忽然破棺而出形真,到底是詐尸還是另有隱情,我是刑警寧澤超全,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布咆霜,位于F島的核電站,受9級特大地震影響嘶朱,放射性物質(zhì)發(fā)生泄漏蛾坯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一疏遏、第九天 我趴在偏房一處隱蔽的房頂上張望脉课。 院中可真熱鬧,春花似錦财异、人聲如沸倘零。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呈驶。三九已至,卻和暖如春疫鹊,著一層夾襖步出監(jiān)牢的瞬間袖瞻,已是汗流浹背司致。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聋迎,地道東北人脂矫。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像砌庄,于是被迫代替她去往敵國和親羹唠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

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