面霸:mq的6大核心問題

前言

最近mq越來越火杠茬,很多公司在用月褥,很多人在用,但是你知道這些問題嗎:

  1. 我們?yōu)槭裁匆胢q瓢喉?
  2. 引入mq會多哪些問題宁赤?
  3. 如何解決這些問題?

本文將會一一為你解答栓票。

1 傳統(tǒng)模式有哪些痛點决左?

1.1 痛點1

有些復雜的業(yè)務系統(tǒng),一次用戶請求可能會同步調用N個系統(tǒng)的接口,需要等待所有的接口都返回了哆窿,才能真正的獲取執(zhí)行結果。

image

這種同步接口調用的方式總耗時比較長厉斟,非常影響用戶的體驗挚躯,特別死在網絡不穩(wěn)定的情況下,極容易出現接口超時問題擦秽。

1.2 痛點2

很多復雜的業(yè)務系統(tǒng)码荔,一般都會拆分成多個子系統(tǒng)。我們在這里以用戶下單為例感挥,請求會先通過訂單系統(tǒng)缩搅,然后分別調用:支付系統(tǒng)、庫存系統(tǒng)触幼、積分系統(tǒng) 和 物流系統(tǒng)硼瓣。

image

系統(tǒng)之間耦合性太高,如果調用的任何一個子系統(tǒng)出現異常置谦,整個請求都會異常堂鲤,對系統(tǒng)的穩(wěn)定性非常不利。

1.3 痛點3

有時候為了吸引用戶媒峡,我們會搞一些活動瘟栖,比如秒殺等。


image

如果用戶少還好谅阿,不會影響系統(tǒng)的穩(wěn)定性半哟。但如果用戶突增,一時間所有的請求都到數據庫签餐,可能會導致數據庫無法承受這么大的壓力寓涨,響應變慢或者直接掛掉。

image

對于這種突然出現的請求峰值氯檐,無法保證系統(tǒng)的穩(wěn)定性缅茉。

2 為什么要用mq?

對于上面?zhèn)鹘y(tǒng)模式的三類問題男摧,我們使用mq就能輕松解決蔬墩。

2.1 異步

對于痛點1:同步接口調用導致響應時間長的問題,使用mq之后耗拓,將同步調用改成異步拇颅,能夠顯著減少系統(tǒng)響應時間。

image

系統(tǒng)A作為消息的生產者乔询,在完成本職工作后樟插,就能直接返回結果了。而無需等待消息消費者的返回黄锤,它們最終會獨立完成所有的業(yè)務功能。

這樣能避免總耗時比較長副编,從而影響用戶的體驗的問題痹届。

2.2 解耦

對于痛點2:子系統(tǒng)間耦合性太大的問題队腐,使用mq之后柴淘,我們只需要依賴于mq悠就,避免了各個子系統(tǒng)間的強依賴問題梗脾。

image

訂單系統(tǒng)作為消息生產者炸茧,保證它自己沒有異常即可稿静,不會受到支付系統(tǒng)等業(yè)務子系統(tǒng)的異常影響改备,并且各個做為消息消費者的業(yè)務子系統(tǒng)之間,也互不影響盐捷。

這樣就把之前復雜的業(yè)務子系統(tǒng)的依賴關系默勾,轉換為只依賴于mq的簡單依賴母剥,從而顯著的降低了系統(tǒng)間的耦合度形导。

2.3 消峰

對于痛點3:由于突然出現的請求峰值朵耕,導致系統(tǒng)不穩(wěn)定的問題阎曹。使用mq后芬膝,能夠起到消峰的作用。

image

訂單系統(tǒng)接收到用戶請求之后,將請求直接發(fā)送到mq哄酝,然后訂單消費者從mq中消費消息祷膳,做寫庫操作直晨。如果出現請求峰值的情況搀军,由于消費者的消費能力有限,會按照自己的節(jié)奏來消費消息勇皇,多的請求不處理,保留在mq的隊列中敛摘,不會對系統(tǒng)的穩(wěn)定性造成影響。

3 引入mq會多哪些問題兄淫?

引入mq后讓我們子系統(tǒng)間耦合性降低了屯远,異步處理機制減少了系統(tǒng)的響應時間,同時能夠有效的應對請求峰值問題氓润,提升系統(tǒng)的穩(wěn)定性。

但是薯鳍,引入mq同時也會帶來一些問題咖气。

3.1 重復消息問題

重復消費問題可以說是mq中普遍存在的問題挨措,不管你用哪種mq都無法避免崩溪。

有哪些場景會出現重復的消息呢浅役?

  1. 消息生產者產生了重復的消息
  2. kafka和rocketmq的offset被回調了
  3. 消息消費者確認失敗
  4. 消息消費者確認時超時了
  5. 業(yè)務系統(tǒng)主動發(fā)起重試
image

如果重復消息不做正確的處理乳幸,會對業(yè)務造成很大的影響粹断,產生重復的數據希柿,或者導致數據異常,比如會員系統(tǒng)多開通了一個月的會員养筒。

3.2 數據一致性問題

很多時候曾撤,如果mq的消費者業(yè)務處理異常的話,就會出現數據一致性問題晕粪。
比如:一個完整的業(yè)務流程是挤悉,下單成功之后,送100個積分巫湘。下單寫庫了装悲,但是消息消費者在送積分的時候失敗了,就會造成數據不一致的情況剩膘,即該業(yè)務流程的部分數據寫庫了衅斩,另外一部分沒有寫庫。

image

如果下單和送積分在同一個事務中怠褐,要么同時成功畏梆,要么同時失敗,是不會出現數據一致性問題的奈懒。

但由于跨系統(tǒng)調用奠涌,為了性能考慮,一般不會使用強一致性的方案磷杏,而改成達成最終一致性即可溜畅。

3.3 消息丟失問題

同樣消息丟失問題,也是mq中普遍存在的問題极祸,不管你用哪種mq都無法避免慈格。

有哪些場景會出現消息丟失問題呢怠晴?

  1. 消息生產者發(fā)生消息時,由于網絡原因浴捆,發(fā)生到mq失敗了蒜田。
  2. mq服務器持久化時,磁盤出現異常
  3. kafka和rocketmq的offset被回調時选泻,略過了很多消息冲粤。
  4. 消息消費者剛讀取消息,已經ack確認了页眯,但業(yè)務還沒處理完梯捕,服務就被重啟了。

導致消息丟失問題的原因挺多的窝撵,生產者傀顾、mq服務器消費者 都有可能產生問題忿族,我再這里就不一一列舉了锣笨。最終的結果會導致消費者無法正確的處理消息蝌矛,而導致數據不一致的情況道批。

3.4 消息順序問題

有些業(yè)務數據是有狀態(tài)的,比如訂單有:下單入撒、支付隆豹、完成、退貨等狀態(tài)茅逮,如果訂單數據作為消息體璃赡,就會涉及順序問題了。如果消費者收到同一個訂單的兩條消息献雅,第一條消息的狀態(tài)是下單碉考,第二條消息的狀態(tài)是支付,這是沒問題的挺身。但如果第一條消息的狀態(tài)是支付侯谁,第二條消息的狀態(tài)是下單就會有問題了,沒有下單就先支付了章钾?


image

消息順序問題是一個非常棘手的問題墙贱,比如:

  • kafka同一個partition中能保證順序,但是不同的partition無法保證順序贱傀。
  • rabbitmq的同一個queue能夠保證順序惨撇,但是如果多個消費者同一個queue也會有順序問題。

如果消費者中使用多線程消費消息府寒,也無法保證順序魁衙。

如果消費消息時同一個訂單的多條消息中报腔,中間的一條消息出現異常情況,順序將會被打亂剖淀。

還有如果生產者發(fā)送到mq中的路由規(guī)則榄笙,跟消費者不一樣,也無法保證順序祷蝌。

3.5 消息堆積

如果消息消費者讀取消息的速度茅撞,能夠跟上消息生產者的節(jié)奏,那么整套mq機制就能發(fā)揮最大作用巨朦。但是很多時候米丘,由于某些批處理,或者其他原因糊啡,導致消息消費的速度小于生產的速度拄查。這樣會直接導致消息堆積問題,從而影響業(yè)務功能棚蓄。

image

這里以下單開通會員為例堕扶,如果消息出現堆積,會導致用戶下單之后梭依,很久之后才能變成會員稍算,這種情況肯定會引起大量用戶投訴。

3.6 系統(tǒng)復雜度提升

這里說的系統(tǒng)復雜度和系統(tǒng)耦合性是不一樣的役拴,比如以前只有:系統(tǒng)A糊探、系統(tǒng)B和系統(tǒng)C 這三個系統(tǒng),現在引入mq之后河闰,你除了需要關注前面三個系統(tǒng)之外科平,還需要關注mq服務,需要關注的點越多姜性,系統(tǒng)的復雜度越高瞪慧。


image

mq的機制需要:生產者、mq服務器部念、消費者弃酌。

有一定的學習成本,需要額外部署mq服務器印机,而且有些mq比如:rocketmq矢腻,功能非常強大,用法有點復雜射赛,如果使用不好多柑,會出現很多問題。有些問題楣责,不像接口調用那么容易排查竣灌,從而導致系統(tǒng)的復雜度提升了聂沙。

4 如何解決這些問題?

mq是一種趨勢初嘹,總體來說對我們的系統(tǒng)是利大于弊的及汉,難道因為它會出現一些問題,我們就不用它了屯烦?

那么我們要如何解決這些問題呢坷随?

4.1 重復消息問題

不管是由于生產者產生的重復消息,還是由于消費者導致的重復消息驻龟,我們都可以在消費者中這個問題温眉。

這就要求消費者在做業(yè)務處理時,要做冪等設計翁狐,如果有不知道如何設計的朋友类溢,可以參考《》,里面介紹得非常詳情露懒。

在這里我推薦增加一張消費消息表闯冷,來解決mq的這類問題。消費消息表中懈词,使用messageId唯一索引蛇耀,在處理業(yè)務邏輯之前,先根據messageId查詢一下該消息有沒有處理過钦睡,如果已經處理過了則直接返回成功蒂窒,如果沒有處理過躁倒,則繼續(xù)做業(yè)務處理荞怒。

image

4.2 數據一致性問題

我們都知道數據一致性分為:

  • 強一致性
  • 弱一致性
  • 最終一致性

而mq為了性能考慮使用的是最終一致性,那么必定會出現數據不一致的問題秧秉。這類問題大概率是因為消費者讀取消息后褐桌,業(yè)務邏輯處理失敗導致的,這時候可以增加重試機制象迎。

重試分為:同步重試異步重試荧嵌。

有些消息量比較小的業(yè)務場景,可以采用同步重試砾淌,在消費消息時如果處理失敗啦撮,立刻重試3-5次,如何還是失敗汪厨,則寫入到記錄表中赃春。但如果消息量比較大,則不建議使用這種方式劫乱,因為如果出現網絡異常织中,可能會導致大量的消息不斷重試锥涕,影響消息讀取速度,造成消息堆積狭吼。

image

而消息量比較大的業(yè)務場景层坠,建議采用異步重試,在消費者處理失敗之后刁笙,立刻寫入重試表破花,有個job專門定時重試。

還有一種做法是疲吸,如果消費失敗旧乞,自己給同一個topic發(fā)一條消息,在后面的某個時間點磅氨,自己又會消費到那條消息尺栖,起到了重試的效果。如果對消息順序要求不高的場景烦租,可以使用這種方式延赌。

4.3 消息丟失問題

不管你是否承認有時候消息真的會丟,即使這種概率非常小叉橱,也會對業(yè)務有影響挫以。生產者、mq服務器窃祝、消費者都有可能會導致消息丟失的問題掐松。

為了解決這個問題,我們可以增加一張消息發(fā)送表粪小,當生產者發(fā)完消息之后大磺,會往該表中寫入一條數據,狀態(tài)status標記為待確認探膊。如果消費者讀取消息之后杠愧,調用生產者的api更新該消息的status為已確認。有個job逞壁,每隔一段時間檢查一次消息發(fā)送表流济,如果5分鐘(這個時間可以根據實際情況來定)后還有狀態(tài)是待確認的消息,則認為該消息已經丟失了腌闯,重新發(fā)條消息绳瘟。

image

這樣不管是由于生產者、mq服務器姿骏、還是消費者導致的消息丟失問題糖声,job都會重新發(fā)消息。

4.4 消息順序問題

消息順序問題是我們非常常見的問題,我們以kafka消費訂單消息為例姨丈。訂單有:下單畅卓、支付、完成蟋恬、退貨等狀態(tài)翁潘,這些狀態(tài)是有先后順序的,如果順序錯了會導致業(yè)務異常歼争。

解決這類問題之前拜马,我們先確認一下,消費者是否真的需要知道中間狀態(tài)沐绒,只知道最終狀態(tài)行不行俩莽?

image

其實很多時候,我真的需要知道的是最終狀態(tài)乔遮,這時可以把流程優(yōu)化一下:

image

這種方式可以解決大部分的消息順序問題扮超。

但如果真的有需要保證消息順序的需求。訂單號路由到不同的partition蹋肮,同一個訂單號的消息出刷,每次到發(fā)到同一個partition

image

4.5 消息堆積

如果消費者消費消息的速度小于生產者生產消息的速度坯辩,將會出現消息堆積問題馁龟。其實這類問題產生的原因很多,如果你想進一步了解漆魔,可以看看我的另一篇文章《我用kafka兩年踩過的一一些非比尋常的坑》坷檩。

那么消息堆積問題該如何解決呢?

這個要看消息是否需要保證順序改抡。

如果不需要保證順序矢炼,可以讀取消息之后用多線程處理業(yè)務邏輯。

image

這樣就能增加業(yè)務邏輯處理速度雀摘,解決消息堆積問題裸删。但是線程池的核心線程數和最大線程數需要合理配置,不然可能會浪費系統(tǒng)資源阵赠。

如果需要保證順序,可以讀取消息之后肌稻,將消息按照一定的規(guī)則分發(fā)到多個隊列中清蚀,然后在隊列中用單線程處理。

image
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末爹谭,一起剝皮案震驚了整個濱河市枷邪,隨后出現的幾起案子,更是在濱河造成了極大的恐慌诺凡,老刑警劉巖东揣,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件践惑,死亡現場離奇詭異,居然都是意外死亡嘶卧,警方通過查閱死者的電腦和手機尔觉,發(fā)現死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芥吟,“玉大人侦铜,你說我怎么就攤上這事≈油遥” “怎么了钉稍?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棺耍。 經常有香客問我贡未,道長,這世上最難降的妖魔是什么蒙袍? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任羞秤,我火速辦了婚禮,結果婚禮上左敌,老公的妹妹穿的比我還像新娘瘾蛋。我一直安慰自己,他們只是感情好矫限,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布哺哼。 她就那樣靜靜地躺著,像睡著了一般叼风。 火紅的嫁衣襯著肌膚如雪取董。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天无宿,我揣著相機與錄音茵汰,去河邊找鬼。 笑死孽鸡,一個胖子當著我的面吹牛描验,可吹牛的內容都是我干的。 我是一名探鬼主播困后,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼杨耙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了巷疼?” 一聲冷哼從身側響起晚胡,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后估盘,有當地人在樹林里發(fā)現了一具尸體瓷患,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年遣妥,在試婚紗的時候發(fā)現自己被綠了擅编。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡燥透,死狀恐怖沙咏,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情班套,我是刑警寧澤肢藐,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吱韭,受9級特大地震影響吆豹,放射性物質發(fā)生泄漏。R本人自食惡果不足惜理盆,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一痘煤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猿规,春花似錦衷快、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至环葵,卻和暖如春调窍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背张遭。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工邓萨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菊卷。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓缔恳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親的烁。 傳聞我的和親對象是個殘疾皇子褐耳,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容