網(wǎng)絡(luò)上已經(jīng)有很多人寫過各種MQ的性能比較和用法了琳袄,我就不再重復(fù)說明了。就寫一些自己對(duì)MQ的理解吧店煞。
為什么要用MQ
MQ的使用場景很多人都可以背得滾瓜爛熟了:業(yè)務(wù)耗時(shí)長获讳,存在并發(fā)問題,需要解耦的業(yè)務(wù)愤诱。那么為什么MQ可以解決這些問題呢云头。首先看看這些場景會(huì)帶來什么問題。
1. 業(yè)務(wù)耗時(shí)長
比如說我需要?jiǎng)?chuàng)建一條違章訂單淫半,這條訂單需要先去查找用戶綁定車輛信息溃槐,會(huì)員包信息,再去另一個(gè)系統(tǒng)查找車主信息科吭,然后再查找違章信息昏滴,再向另一個(gè)系統(tǒng)同步下單信息等等20多個(gè)步驟,總共需要3秒時(shí)間对人。這3秒時(shí)間谣殊,是服務(wù)器處理一條訂單所需要的時(shí)間。此時(shí)如果有100個(gè)用戶下單牺弄,100單同時(shí)卡在這3秒鐘內(nèi)姻几,服務(wù)器所有的性能用來處理這堆積的100單,就會(huì)造成服務(wù)器性能下降势告,導(dǎo)致處理一單花費(fèi)的時(shí)間更長蛇捌。假如是5秒,那如果此時(shí)再有人下單咱台,就會(huì)有更多的訂單堵塞在這里豁陆。然后性能繼續(xù)下降,花費(fèi)的時(shí)間更多吵护,死循環(huán)了盒音,服務(wù)器總得要崩掉表鳍。
添加消息中間件,消息中間件可以同時(shí)接收萬級(jí)的請(qǐng)求祥诽,并把這些請(qǐng)求存儲(chǔ)在消息隊(duì)列中譬圣。下游創(chuàng)建訂單的業(yè)務(wù)花費(fèi)了3秒,處理完后雄坪,消息隊(duì)列再釋放下一個(gè)請(qǐng)求過來厘熟,這樣就變成了請(qǐng)求一個(gè)接一個(gè)地過來,不會(huì)有很多請(qǐng)求堆積在服務(wù)器內(nèi)维哈,造成性能下降绳姨。
2. 存在并發(fā)問題
比如說我要做一個(gè)搶紅包系統(tǒng),用戶A和B同時(shí)從數(shù)據(jù)庫查找到一個(gè)紅包阔挠,然后A先領(lǐng)取了紅包的錢飘庄,把紅包的狀態(tài)改為已獲取。此時(shí)B已經(jīng)把這個(gè)紅包查詢出來了购撼,再領(lǐng)取紅包的錢跪削,如果沒有加樂觀鎖,再次把紅包的狀態(tài)改為已獲取迂求,這樣就造成了A碾盐、B兩個(gè)人獲取到了同一個(gè)紅包。
如果在這個(gè)問題中添加樂觀鎖揩局,B去修改紅包狀態(tài)的時(shí)候就會(huì)報(bào)錯(cuò)毫玖,似乎領(lǐng)取紅包的問題就解決了。但如果多人同時(shí)搶到紅包凌盯,就只有第一個(gè)人A能夠成功領(lǐng)取付枫,其他人都是報(bào)錯(cuò),用戶體驗(yàn)就比較差十气。
添加消息中間件,同樣地將這些并發(fā)的請(qǐng)求轉(zhuǎn)變?yōu)橐粋€(gè)接一個(gè)的請(qǐng)求春霍,當(dāng)用戶A把紅包的領(lǐng)取狀態(tài)修改完成了砸西,用戶B才去獲取下一個(gè)紅包,就不會(huì)造成A址儒、B同時(shí)獲取到同一個(gè)紅包的情況芹枷。
3. 需要解耦的業(yè)務(wù)
比如說用戶購買了會(huì)員包之后,需要給用戶發(fā)送一條手機(jī)短信莲趣,一條支付寶模版消息鸳慈。如果把這些流程和下單購買會(huì)員包寫在一起,如果發(fā)送短信失敗喧伞,購買會(huì)員包也會(huì)失敗走芋。我不希望支付流程會(huì)被發(fā)送短信流程所影響绩郎。
這就是需要解耦的場景,這個(gè)時(shí)候有兩種方式可以選擇:1. 創(chuàng)建新線程翁逞,單獨(dú)去執(zhí)行發(fā)短信的流程肋杖。2. 使用消息中間件,異步發(fā)送短信挖函。這兩種方式各有優(yōu)缺點(diǎn)状植,視情況選擇。
新線程:使用方便怨喘,不用額外添加組件津畸。但是無法查看執(zhí)行狀態(tài),如果業(yè)務(wù)消耗的時(shí)間長必怜,同一時(shí)間就會(huì)有較多的線程被占用肉拓。解耦的業(yè)務(wù),如果發(fā)生改變需要重啟棚赔,主業(yè)務(wù)也要重啟帝簇。
消息中間件:新增加了一個(gè)組件,會(huì)增加設(shè)計(jì)上的復(fù)雜性靠益,就要多考慮新增組件帶來的問題丧肴,比如如何使消息百分百發(fā)送。同時(shí)MQ需要消耗網(wǎng)絡(luò)資源胧后。好處就是能夠查看系統(tǒng)運(yùn)行狀態(tài)芋浮,解耦的業(yè)務(wù)發(fā)生改變需要重啟,可以單獨(dú)重啟而不影響主流程壳快。
簡單地說纸巷,單工程架構(gòu),使用新線程比較好眶痰,分布式架構(gòu)瘤旨,選擇消息中間件∈或者選擇終極方式:創(chuàng)建一個(gè)線程存哲,讓這個(gè)線程只做一件事——給MQ發(fā)消息。