为什么需要消息队列MQ
主要原因:是在高并發(fā)情況下,由于來不及同步處理,請求往往會發(fā)生堵塞,比如諸多的insert、update之類的請求同時到達(dá)mysql,直接導(dǎo)致無數(shù)的行鎖表鎖,甚至最后請求會堆積很多,從而觸發(fā)大量的too mang? connnections錯誤。通過消息隊(duì)列,我們可以異步處理請求,從而緩解系統(tǒng)的壓力。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MQ(message queue)是一種跨進(jìn)程的通信機(jī)制,用于上下游傳遞消息。
mq的特點(diǎn):
1、先進(jìn)先出
? ? ? ?不能先進(jìn)先出,都不能說是隊(duì)列了,消息隊(duì)列的順序在入隊(duì)時基本已經(jīng)確定,一般是不需要人工干預(yù)的。而且最重要的是,數(shù)據(jù)是只有一條數(shù)據(jù)在使用中,這也是mq在眾多場景中被使用的原因。
2、發(fā)布訂閱
? ? ? ?發(fā)布訂閱是一種很高效的處理方式,如果不發(fā)生阻塞,基本可以當(dāng)做是同步操作。這種處理方式能非常有效的提升服務(wù)器利用率,這樣的應(yīng)用場景非常廣泛。
3、持久化
? ? ? ?持久化確保MQ的使用不只是一個部分場景的輔助工具,而是讓MQ能像數(shù)據(jù)庫一樣存儲核心的數(shù)據(jù)。
4、分布式
? ? ? 在現(xiàn)在大流量、大數(shù)據(jù)的使用場景下,只支持單體應(yīng)用的服務(wù)器軟件基本是無法使用的,支持分布式的部署,才能被廣泛使用。而且,MQ的定位就是一個高性能的中間件。
應(yīng)用場景
基于上文所述的特點(diǎn),那么MQ就衍生出了很多的使用場景,在大型的系統(tǒng)中,應(yīng)用非常廣泛,這里我們就列舉一下常見的應(yīng)用場景。
應(yīng)用解耦(異步)?
系統(tǒng)之間進(jìn)行數(shù)據(jù)交互時,在時效性和穩(wěn)定性之間我們都要進(jìn)行選擇;基于線程的異步處理,能確保用戶體驗(yàn),但在極端情況下,可能會出現(xiàn)異常,影響系統(tǒng)的穩(wěn)定性,而同步調(diào)用很多時候無法保證理想的性能,那么我們就可以用mq來進(jìn)行處理,上游系統(tǒng)將數(shù)據(jù)投遞到mq,下游系統(tǒng)取mq的數(shù)據(jù)進(jìn)行消費(fèi),投遞和消費(fèi)可以用同步的方式處理,因?yàn)閙q接收數(shù)據(jù)的性能是非常高的,不會影響上游系統(tǒng)的性能,那么下游系統(tǒng)的及時率能保證嗎?當(dāng)然可以,不然就不會有下面的一個應(yīng)用場景。
通知
?這里就用到了前文一個重要的特點(diǎn),發(fā)布訂閱,下游系統(tǒng)一直在監(jiān)聽MQ的數(shù)據(jù),如果MQ有數(shù)據(jù),下游系統(tǒng)則會按照?先進(jìn)先出?這樣的規(guī)則,?逐條進(jìn)行消費(fèi)?,而上游系統(tǒng)只需要將數(shù)據(jù)存入MQ里,這樣既降低了不同系統(tǒng)之間的耦合度,同時也確保了消息通知的及時性,而且也不影響上游系統(tǒng)的性能。
限流
上文有說了一個非常重要的特性,MQ?數(shù)據(jù)是只有一條數(shù)據(jù)在使用中。?在很多存在并發(fā),而又對數(shù)據(jù)一致性要求高,而且對性能要求也高的場景,如何保證,那么MQ就能起這個作用了。不管多少流量進(jìn)來,MQ都會讓你遵守規(guī)則,排除處理,不會因?yàn)槠渌?#xff0c;導(dǎo)致并發(fā)的問題,而出現(xiàn)很多意想不到臟數(shù)據(jù)。
數(shù)據(jù)分發(fā)
MQ的發(fā)布訂閱肯定不是只是簡單的一對一,一個上游和一個下游的關(guān)系,MQ中間件基本都是支持一對多或者廣播的模式,而且都可以根據(jù)規(guī)則選擇分發(fā)的對象。這樣上游的一份數(shù)據(jù),眾多下游系統(tǒng)中,可以根據(jù)規(guī)則選擇是否接收這些數(shù)據(jù),這樣擴(kuò)展性就很強(qiáng)了。
PS:上文中的上游和下游,在MQ更多的是叫做生產(chǎn)者(producer)和消費(fèi)者(consumer)
分布式事務(wù)
分布式事務(wù)是我們開發(fā)中一直盡量避免的一個技術(shù)點(diǎn),但是,現(xiàn)在越來越多的系統(tǒng)是基于微服務(wù)架構(gòu)開發(fā),那么分布式事務(wù)成為必須要面對的難題,解決分布式事務(wù)有一個比較容易理解的方案,就是二次提交。基于MQ的特點(diǎn),MQ作為二次提交的中間節(jié)點(diǎn),負(fù)責(zé)存儲請求數(shù)據(jù),在失敗的情況可以進(jìn)行多次嘗試,或者基于MQ中的隊(duì)列數(shù)據(jù)進(jìn)行回滾操作,是一個既能保證性能,又能保證業(yè)務(wù)一致性的方案,當(dāng)然,這個方案的主要問題就是定制化較多,有一定的開發(fā)工作量。
應(yīng)用示例
為了更加直觀的展示MQ的應(yīng)用場景,這里我們就用一個常見的電商系統(tǒng)中的幾個業(yè)務(wù),來具體說明下MQ在實(shí)際開發(fā)中應(yīng)用場景。
我們的實(shí)際場景大概是一個基于微服務(wù)架構(gòu)的電商系統(tǒng),分為用戶微服務(wù)、商品微服務(wù)、訂單微服務(wù)、促銷微服務(wù)等。基于微服務(wù)模式開發(fā)的系統(tǒng),MQ的使用場景更多,下面我們逐一說明:
1、注冊后我們可能需要做很多初始化的操作,如:調(diào)用郵件服務(wù)器發(fā)送郵件、調(diào)用促銷服務(wù)贈送優(yōu)惠劵、下發(fā)用戶數(shù)據(jù)到客戶關(guān)系系統(tǒng)等。那么這時候我們將這些操作去監(jiān)聽MQ,當(dāng)用戶注冊成功過后,通過MQ通知其他業(yè)務(wù)進(jìn)行操作。確保注冊用戶的性能。
2、后臺發(fā)布商品的時候,商品數(shù)據(jù)需要從數(shù)據(jù)庫中轉(zhuǎn)換成搜索引擎數(shù)據(jù)(基于elasticsearch),那么我們應(yīng)該將商品寫入數(shù)據(jù)庫后,再寫入到MQ,然后通過監(jiān)聽MQ來生成elasticsearch對應(yīng)的數(shù)據(jù)。
3、用戶下單后,24小時未支付,需要取消訂單。以前我們可能是定時任務(wù)循環(huán)查詢,然后取消訂單。實(shí)際上,我更推薦類似延遲MQ的方式,避免了很多無效的數(shù)據(jù)庫查詢,將一個MQ設(shè)置為24小時后才讓消費(fèi)者消費(fèi)掉,這樣很大程度上能減輕服務(wù)器壓力。
4、支付完成后,需要及時的通知子系統(tǒng)(進(jìn)銷存系統(tǒng)發(fā)貨,用戶服務(wù)積分,發(fā)送短信)進(jìn)行下一步操作,但是,支付回調(diào)我們都是需要保證高性能的,所以,我應(yīng)該直接修改數(shù)據(jù)庫狀態(tài),存入MQ,讓MQ通知子系統(tǒng)做其他非實(shí)時的業(yè)務(wù)操作。這樣能保證核心業(yè)務(wù)的高效及時。
注意事項(xiàng)
其實(shí),還有非常多的業(yè)務(wù)場景,是可以考慮用MQ方式的,但是很多時候,也會存在濫用的情況,我們需要清楚認(rèn)識我們的業(yè)務(wù)場景:
發(fā)驗(yàn)證碼短信、郵件,這種過分依賴外部,而且時效性可以接收幾十秒延遲的,其實(shí)更好的方式是多線程異步處理,而不是過多依賴MQ。
秒殺搶購確保庫存不為負(fù)數(shù),更多的依賴高性能緩存(如redis),以及強(qiáng)制加鎖,千萬不要依賴消費(fèi)者最終的返回結(jié)果。(實(shí)際工作中已經(jīng)看到好幾個這樣的案例了)上游-下游?這種直接的處理方式效率肯定是比?上游-MQ-下游?方式要高,MQ效率高,是因?yàn)?#xff0c;我只是上游-MQ?這個階段就當(dāng)做已經(jīng)成功了
?
轉(zhuǎn)載于:https://www.cnblogs.com/pdd-666888/p/9447164.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的为什么需要消息队列MQ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cogs 76. [NOIP2007]
- 下一篇: react.js从入门到精通(一)