MQ解決什么問(wèn)題?
要了解MQ的必要性,需要先了解一下微服務(wù)的產(chǎn)生與出現(xiàn)的問(wèn)題。只有了解了問(wèn)題產(chǎn)生的原因才能明白MQ的作用。
舉個(gè)栗子:支付業(yè)務(wù)
單服務(wù)
傳統(tǒng)的服務(wù)以單服務(wù)為主,所有的操作由一個(gè)服務(wù)器中的一個(gè)服務(wù)提供,如下圖,支付、修改訂單狀態(tài)、創(chuàng)建物流訂單。

三個(gè)步驟可以放在一個(gè)jdbc事務(wù)中。一旦哪個(gè)步驟出錯(cuò),其它兩個(gè)步驟都會(huì)放棄。
以防止出現(xiàn):支付完了,沒(méi)有訂單。訂單狀態(tài)已經(jīng)更改,沒(méi)有產(chǎn)生物流訂單。要么都成功,要么都失敗。以保證業(yè)務(wù)的正確性。
微服務(wù)
在微服務(wù)的環(huán)境下,會(huì)將三個(gè)步驟拆分成三個(gè)服務(wù),例如:支付服務(wù),訂單服務(wù),物流服務(wù)。三者顧名思義只做好自己的一件事情。

情況會(huì)變復(fù)雜,同樣以支付業(yè)務(wù)為例,三個(gè)步驟需要有服務(wù)間的調(diào)用,如下圖,有兩次調(diào)用產(chǎn)生,服務(wù)間調(diào)用一般有兩種方式:restful 的http與RPC。這里不討論兩者的區(qū)別。
微服務(wù)化的好處:化整為零,單一服務(wù)制作單一的事情,可以防止單服務(wù)無(wú)線膨脹。無(wú)論從開(kāi)發(fā),測(cè)試,運(yùn)維方面單個(gè)服務(wù)都是占優(yōu)勢(shì)的。
微服務(wù)帶來(lái)的問(wèn)題:
- 分布式事務(wù)
服務(wù)間調(diào)用難以保持一致性。例如上圖中的兩次調(diào)用。因?yàn)槿齻€(gè)步驟操作的不是同一個(gè)數(shù)據(jù)庫(kù),導(dǎo)致無(wú)法使用jdbc事務(wù)管理以達(dá)到一致性。而且兩次服務(wù)調(diào)用,因?yàn)樯婕暗綇?fù)雜的網(wǎng)絡(luò)環(huán)境,很容易出現(xiàn),服務(wù)調(diào)用失敗。所以,微服務(wù)化之后出現(xiàn)的一個(gè)很?chē)?yán)重的問(wèn)題就是,分布式事務(wù)問(wèn)題如何解決。
分布式事務(wù)?
分布式事務(wù)有幾種解決方案,這里僅討論MQ如何解決分布式事務(wù)。
- 兩階段提交
- 補(bǔ)償事務(wù)
- 本地消息表
- MQ 事務(wù)消息
MQ作為解決分布式事務(wù)的一種,是如何解決分布式事務(wù)問(wèn)題的,如下圖,支付服務(wù)完成支付步驟后,往MQ發(fā)送一條已支付消息,訂單服務(wù)收到消息后更改訂單狀態(tài)。

有人就想說(shuō),這沒(méi)什么區(qū)別么,甚至加了一層MQ,導(dǎo)致需要兩次調(diào)用,更復(fù)雜風(fēng)險(xiǎn)更大?
MQ解決分布式事務(wù)是這樣做的,A服務(wù)保證消息發(fā)送成功,MQ保證消息不會(huì)丟失,B服務(wù)保證消息消費(fèi)成功。會(huì)出現(xiàn)以下情況:
- A服務(wù)生產(chǎn)消息失敗,回滾支付操作,業(yè)務(wù)回到最初狀態(tài),保證了一致性。
- A服務(wù)生產(chǎn)消息成功,完成支付操作,MQ宕機(jī),MQ重啟后,消息還存在,訂單服務(wù)消費(fèi)消息,完成修改訂單操作。保證了一致性。
- A服務(wù)生產(chǎn)消息成功,MQ良好,訂單服務(wù)消費(fèi)消息失敗。但是消息還存在,等訂單服務(wù)重啟后繼續(xù)消費(fèi)消息,保證了一致性。
以上就是分布式事務(wù)中的最終一致性:即使無(wú)法做到強(qiáng)一致性,但每個(gè)應(yīng)用都可以根據(jù)自身業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹?lái)使系統(tǒng)達(dá)到最終一致性。
MQ作為完成最終一致性的一種工具。RocketMQ也有自己的事務(wù)消息更簡(jiǎn)單的解決以上問(wèn)題。