前言:關(guān)于消息隊列應(yīng)該大家都不陌生,在實際的項目中消息隊列也無處不在,今天我和大家分享一下關(guān)于消息隊列的問題锈死。
1衡奥、消息隊列定義
消息隊列大家又經(jīng)常稱為MQ(message queue),從字面的含義來看就是一個存放消息的容器铡溪。
2瓷胧、消息隊列應(yīng)用場景
2.1趟庄、異步處理
2.2括细、系統(tǒng)解耦
2.3、流量削峰
3戚啥、消息隊列順序性
? 提到mq那么我們必然會討論mq順序性問題,比如生產(chǎn)者發(fā)送消息1,2,3...對于消費者必須按照1,2,3...這樣的順序來消費,那么消息隊列應(yīng)該怎么樣去考慮這樣事情呢,有人說了消息隊列是先進(jìn)先出不就保證了順序性,其實并非如此,而且想通過隊列來保證順序性是非常困難的,那么我們來看看為什么說非常困難的奋单。
對于生產(chǎn)者而言
比如生產(chǎn)者連續(xù)發(fā)送1、2猫十、3但是不久2和3返回結(jié)果成功,唯獨1返回結(jié)果是失敗,這個時候如果我們重發(fā)1那么順序肯定就會亂了览濒。
對于存儲端而言
?消息隊列不可能分區(qū)進(jìn)行存儲,也就是一個topic的消息只能采用一個隊列存儲,如果一個topic采用多個隊列就不可能保證順序
對于消費者而言
對于消費端來說還不可以并行消費,也就是不可以開啟多線程或者多個客戶端來進(jìn)行消費
3.1、消息隊列順序性分析1:
假設(shè)我們現(xiàn)在想要保證s1和s2兩條消息順序被消費可能想設(shè)計如上圖所示,假定生產(chǎn)者先發(fā)送s1然后在發(fā)送s2,如果想保證s1先被消費,那么需要s1到達(dá)消費端后在通知mq2,然后mq2在發(fā)送消息拖云。但是其實這是理想的模型,可能會出現(xiàn)如下2個問題
1贷笛、s1不一定要比s2先到mq集群(比如網(wǎng)絡(luò)延遲)
2、s2到達(dá)mq集群并且已經(jīng)消費完畢,s1還沒到達(dá)mq集群,這就會出現(xiàn)亂序
所有我們想要s1比s2先消費最簡單粗暴的方式就是s1和s2發(fā)送同一臺server上,這樣根據(jù)隊列先進(jìn)先出原則,肯定s1要比s2先消費
3.2宙项、消息隊列順序性分析2:
但是這種模型僅僅是理論上的可行,因為可能出現(xiàn)網(wǎng)絡(luò)延遲,比如s2比是s1先到達(dá)消費端,我們同樣無法保證消息的順序,這樣一來我們可能發(fā)送s1等消費者響應(yīng)后然后在發(fā)s2乏苦。
3.3、消息隊列順序性分析3:
但是我們知道消費者可能出現(xiàn)2種情況
1尤筐、消費者沒有響應(yīng)(可能消費成功沒有響應(yīng),也可能消費失敗沒有響應(yīng))
2汇荐、消費者響應(yīng)成功
對于沒有響應(yīng)的mq集群可以進(jìn)行重發(fā)消息,如果消費成功重發(fā)就會導(dǎo)致消息重新處理,這樣一來就會帶來新的問題,重復(fù)問題下面說
綜上我們可以得出想保證消息順序性最簡單可行方式就是生產(chǎn)者->mq->消費者這樣一一對應(yīng)關(guān)系,但是同樣會帶來如下2個問題
1洞就、吞吐量不足
2、可用性低
3.4拢驾、消息隊列順序性分析4:
任何設(shè)計都離不開業(yè)務(wù)的本身,我們可以從業(yè)務(wù)來考慮順序消息
1奖磁、不關(guān)注亂序的應(yīng)用實際大量存在
2、隊列無序不表示消息無序
注釋:對于同一種消息放入同一個隊列中,同一種消息可以通過topic主題來進(jìn)行標(biāo)記繁疤。
綜上我們可以可以總結(jié)出來為了保證消息的順序性要從生產(chǎn)者咖为、存儲端、消費者三個角度來考慮
1稠腊、生產(chǎn)端必須保證消息成功發(fā)送以后才能繼續(xù)發(fā)送第二條
2躁染、存儲端必須要求同一種消息必須存放在同一個隊列中
3、消費端不可以采用并發(fā)消費
4架忌、消息隊列重復(fù)性
消息重復(fù)由業(yè)務(wù)端來保證如上圖
5吞彤、消息隊列可靠性
生產(chǎn)者:ack確認(rèn)機(jī)制消息重發(fā)
消費者:手動ack確認(rèn),消息重新請求,或者重試等
消息隊列:如下圖所示
1、對于業(yè)務(wù)方進(jìn)行限流,避免惡意刷消息
2叹放、服務(wù)器采用負(fù)載均衡避免一臺服務(wù)宕機(jī)而不可用
3饰恕、消息采用持久化,避免斷電等原因?qū)е孪G失
6、消息隊列存儲
消息隊列存儲一般采用邏輯存儲和物理存儲如下圖所示
1井仰、邏輯存儲放入內(nèi)存,主要存儲偏移量埋嵌、消息主題等,同時將存儲內(nèi)容刷入磁盤避免丟失
2、物理采用文件進(jìn)行存儲,定期對文件進(jìn)行歸檔
6俱恶、消息隊列的缺點
6.1雹嗦、服務(wù)可用性降低
加入消息隊列后,如果出現(xiàn)mq集群宕機(jī),那么就可能會導(dǎo)致服務(wù)不可用
6.2、服務(wù)復(fù)雜度增加
加入消息隊列以后就不得不考慮消息一致性合是、可靠性了罪、重復(fù)性等問題無疑加大了服務(wù)的難度
歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)開發(fā): 854393687
群內(nèi)提供免費的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)聪全、高性能及分布式泊藕、Jvm性能調(diào)優(yōu)、Spring源碼难礼,MyBatis吱七,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料)合理利用自己每一分每一秒的時間來學(xué)習(xí)提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰鹤竭!趁年輕,使勁拼景醇,給未來的自己一個交代臀稚!