網(wǎng)絡(luò)上已經(jīng)有很多人寫過(guò)各種MQ的性能比較和用法了,我就不再重復(fù)說(shuō)明了。就寫一些自己對(duì)MQ的理解吧。
為什么要用MQ
MQ的使用場(chǎng)景很多人都可以背得滾瓜爛熟了:業(yè)務(wù)耗時(shí)長(zhǎng),存在并發(fā)問(wèn)題,需要解耦的業(yè)務(wù)。那么為什么MQ可以解決這些問(wèn)題呢。首先看看這些場(chǎng)景會(huì)帶來(lái)什么問(wèn)題。
1. 業(yè)務(wù)耗時(shí)長(zhǎng)
比如說(shuō)我需要?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ù)器所有的性能用來(lái)處理這堆積的100單,就會(huì)造成服務(wù)器性能下降,導(dǎo)致處理一單花費(fèi)的時(shí)間更長(zhǎng)。假如是5秒,那如果此時(shí)再有人下單,就會(huì)有更多的訂單堵塞在這里。然后性能繼續(xù)下降,花費(fèi)的時(shí)間更多,死循環(huán)了,服務(wù)器總得要崩掉。
添加消息中間件,消息中間件可以同時(shí)接收萬(wàn)級(jí)的請(qǐng)求,并把這些請(qǐng)求存儲(chǔ)在消息隊(duì)列中。下游創(chuàng)建訂單的業(yè)務(wù)花費(fèi)了3秒,處理完后,消息隊(duì)列再釋放下一個(gè)請(qǐng)求過(guò)來(lái),這樣就變成了請(qǐng)求一個(gè)接一個(gè)地過(guò)來(lái),不會(huì)有很多請(qǐng)求堆積在服務(wù)器內(nèi),造成性能下降。
2. 存在并發(fā)問(wèn)題
比如說(shuō)我要做一個(gè)搶紅包系統(tǒng),用戶A和B同時(shí)從數(shù)據(jù)庫(kù)查找到一個(gè)紅包,然后A先領(lǐng)取了紅包的錢,把紅包的狀態(tài)改為已獲取。此時(shí)B已經(jīng)把這個(gè)紅包查詢出來(lái)了,再領(lǐng)取紅包的錢,如果沒(méi)有加樂(lè)觀鎖,再次把紅包的狀態(tài)改為已獲取,這樣就造成了A、B兩個(gè)人獲取到了同一個(gè)紅包。
如果在這個(gè)問(wèn)題中添加樂(lè)觀鎖,B去修改紅包狀態(tài)的時(shí)候就會(huì)報(bào)錯(cuò),似乎領(lǐng)取紅包的問(wèn)題就解決了。但如果多人同時(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ù)
比如說(shuō)用戶購(gòu)買了會(huì)員包之后,需要給用戶發(fā)送一條手機(jī)短信,一條支付寶模版消息。如果把這些流程和下單購(gòu)買會(huì)員包寫在一起,如果發(fā)送短信失敗,購(gòu)買會(huì)員包也會(huì)失敗。我不希望支付流程會(huì)被發(fā)送短信流程所影響。
這就是需要解耦的場(chǎng)景,這個(gè)時(shí)候有兩種方式可以選擇:1. 創(chuàng)建新線程,單獨(dú)去執(zhí)行發(fā)短信的流程。2. 使用消息中間件,異步發(fā)送短信。這兩種方式各有優(yōu)缺點(diǎn),視情況選擇。
新線程:使用方便,不用額外添加組件。但是無(wú)法查看執(zhí)行狀態(tài),如果業(yè)務(wù)消耗的時(shí)間長(zhǎng),同一時(shí)間就會(huì)有較多的線程被占用。解耦的業(yè)務(wù),如果發(fā)生改變需要重啟,主業(yè)務(wù)也要重啟。
消息中間件:新增加了一個(gè)組件,會(huì)增加設(shè)計(jì)上的復(fù)雜性,就要多考慮新增組件帶來(lái)的問(wèn)題,比如如何使消息百分百發(fā)送。同時(shí)MQ需要消耗網(wǎng)絡(luò)資源。好處就是能夠查看系統(tǒng)運(yùn)行狀態(tài),解耦的業(yè)務(wù)發(fā)生改變需要重啟,可以單獨(dú)重啟而不影響主流程。
簡(jiǎn)單地說(shuō),單工程架構(gòu),使用新線程比較好,分布式架構(gòu),選擇消息中間件?;蛘哌x擇終極方式:創(chuàng)建一個(gè)線程,讓這個(gè)線程只做一件事——給MQ發(fā)消息。