分布式中间件之消息中间件
?中間件是什么
首先,一個擁有信息化建設積累的公司內(nèi)部可能同時運行著多個不同的業(yè)務系統(tǒng),而這些系統(tǒng)可能基于不同操作系統(tǒng),不同存儲數(shù)據(jù)的數(shù)據(jù)庫等,若需要將這些信息系統(tǒng)可以結合成一個協(xié)同工作的整體,實現(xiàn)企業(yè)跨平臺、分布式應用,就需要一個中介者完成這個使命,而中間件便是天選之子,它處于操作系統(tǒng)和應用程序之間,它是脫離了具體的設計目標,而具備提供普遍獨立功能需求的模塊(可替換),屏蔽了底層操作系統(tǒng)的復雜性,使得開發(fā)人員面對簡單而統(tǒng)一的開發(fā)環(huán)境,將注意力放在業(yè)務的實現(xiàn)上。中間件的使用不僅是對于開發(fā)而言更加簡便,也降低了后續(xù)的系統(tǒng)維護成本。常用的中間件包括負載均衡中間件(Nginx、CDN),分布式消息中間件(RabbitMQ、Kafka),緩存中間件(MemCache、Redis),緩存中間件(Mycat、ShardingJdbc),等
注意:項目架構和重構中國,需要謹慎思考和斟酌,因為任何技術的融入和變化都會增加相應成本,建議初創(chuàng)公司或者業(yè)務比較單一等先選擇單體架構即可,后續(xù)隨著業(yè)務或者項目不斷驅動再加入對應的技術
消息中間件是什么
在理解消息中間件是什么之前,我們先普及一下單體架構和分布式架構區(qū)別;
單體架構
公司開發(fā)初期架構中,基本都采取的是單體架構模式,他的特點就是把所有業(yè)務和模塊代碼放在一個工程下。單體架構本質(zhì)就是我們發(fā)起一個請求,由JVM分配線程并調(diào)用需要使用的服務串行處理響應。引發(fā)的問題就是:我們升級其中一個模塊或者迭代都需要整個項目重新編譯和重新發(fā)布。這種架構存在的問題包括:代碼耦合度太高,運維成本高,不利于升級架構
分布式架構
分布式架構的使用是建立在業(yè)務驅動下使用,相比單體架構,分布式架構中一個請求則是由多個系統(tǒng)(服務)共同協(xié)同完成,JVM和環(huán)境都是獨立的。優(yōu)勢在于:a.合理分配服務資源 b.系統(tǒng)獨立維護和部署,耦合度低,可插拔 c.每個系統(tǒng)的架構所使用的技術棧可靈活選擇(比如Java/PHP/GO) d.彈性部署,不會造成平臺因部署造成癱瘓
缺點:a.學習成本高,技術棧多 b.人員/運維/服務器成本增高 c.系統(tǒng)面臨的容錯性也會成倍增加
消息中間件
消息中間件是在消息傳輸過程中保存消息的一種容器,主要應用于分布式系統(tǒng)之間進行通信.通信過程中服務之間采取異步方式,被用于緩沖或緩解高峰期工作負載等業(yè)務場景
分布式架構中消息中間件示例?從示意圖可以了解什么是消息中間件(本質(zhì)就是接收數(shù)據(jù)->存儲數(shù)據(jù)->發(fā)送數(shù)據(jù)):
1.利用可靠的消息傳遞機制進行各個服務間的通訊
2.利用消息傳遞和排隊機制,在分布式架構中擴展服務間通訊
消息中間件的組成部分
1.消息隊列協(xié)議
消息隊列協(xié)議都是基于TCP/IP協(xié)議實現(xiàn)的一種約定俗成的規(guī)范,目的是讓客戶端(Java/Go/Python)進行無障礙通訊,且這種協(xié)議下的各種實現(xiàn)必須具有持久性、高可用、高可靠性能。常見的消息隊列協(xié)議包括:AMQP、MQTT、kafka、OpenMessage
AMQP協(xié)議-實現(xiàn)者RabbitMq、ActiveMQ
MQTT協(xié)議-物聯(lián)網(wǎng)重要組成部分
?
?OpenMessage協(xié)議-實現(xiàn)者RocketMQ(謹慎,萬一公司倒閉,若研發(fā)能力不足則需要重構)
kafka協(xié)議-實現(xiàn)者Kafka(由于沒有定義復雜的報文頭,基于二進制傳輸更接近于底層,但不支持事務)
彩蛋:為什么消息中間件不直接使用 http 協(xié)議?
因為 http 請求報文頭和響應報文頭是比較復雜的,包含了cookie、數(shù)據(jù)的加密解密、狀態(tài)碼、響應碼等附加的功能;對于消息而言,并不需要這么復雜的附加功能,目的只有負責數(shù)據(jù)傳遞、存儲、分發(fā),只需要簡潔,快速保證高性能即可。
大部分情況下 http 都是短鏈接,當請求到響應這個過程出現(xiàn)中斷后不會進行持久化,會造成請求的丟失。而對于消息中間件的業(yè)務場景,當出現(xiàn)問題和故障要時必須對數(shù)據(jù)或進行持久化,目的就是為了保證消息和數(shù)據(jù)的高可靠和穩(wěn)健的運行
2.消息隊列持久化
將消息數(shù)據(jù)存儲到磁盤,使得數(shù)據(jù)可以永久保存,而不是存儲在內(nèi)存隨服務器重啟斷開而消失
消息數(shù)據(jù)持久化3.消息的分發(fā)策略
MQ消息包含了生產(chǎn)者、存儲消息、消費者,當生產(chǎn)者生成消息以及MQ存儲數(shù)據(jù)到磁盤后,消費者是如何獲取消息的呢?其實MQ采取的是一種推送機制,而消息推送分發(fā)的策略包括如下幾種:
消息分發(fā)策略對比其中:
? ? ? ? a.發(fā)布訂閱:所有MQ實現(xiàn)者均支持,對于MQ隊列的數(shù)據(jù),都會推送給每一個消費者?,比如有90條數(shù)據(jù),那么每個消費者都會收到90條數(shù)據(jù)
? ? ? ? b.輪詢分發(fā):MQ按照公平分發(fā)給每個消費者(不考慮各消費者服務性能的高低),且不會重復消費數(shù)據(jù),但不會按照順序消費。比如:有90條數(shù)據(jù),那么每個消費者都會收到30條數(shù)據(jù)
? ? ? ? c.公平分發(fā):不會重復消費數(shù)據(jù),但相比輪詢分發(fā),它會依據(jù)各消費者服務器性能有所傾斜,即能者多勞。比如:消費者甲qp為1000/ms,乙為100/ms,丙為300/ms,則對于90條數(shù)據(jù),可能甲會消費5條,乙消費50條,丙消費35條
? ? ? ? d.重發(fā):當某個消費者出現(xiàn)異常故障,則隊列會出現(xiàn)消息堆積,當消費者正常后,可重新發(fā)送消息,保證高可靠。但Kafka不支持重發(fā)
4.消息隊列高可用和高可靠
高可用:指的是服務在某條件或時刻下處于可執(zhí)行狀態(tài)的能力,一般采取集群部署保證高可用
集群模式1-Master-slave主從共享數(shù)據(jù)部署
????????生產(chǎn)者將數(shù)據(jù)發(fā)送到Master消息隊列節(jié)點,所有Slave節(jié)點和master共享存儲數(shù)據(jù),一旦master節(jié)點故障無法寫入,則由slave節(jié)點繼續(xù)服務,保證高可用,適合小型項目。但共享的數(shù)據(jù)一旦丟失,那么master和slave就沒有意義了,所以出現(xiàn)了主從同步或者主從復制模式
Master-slave主從共享集群模式2-Master-slave主從同步數(shù)據(jù)部署
????????這種寫入數(shù)據(jù)依然在master節(jié)點上,但同時master會同步數(shù)據(jù)到slave節(jié)點形成副本,對于存在多個消費者可以達到負載均衡效果,同時消息的拷貝和同步也會占用比較多的帶寬和網(wǎng)絡資源
Master-slave主從同步數(shù)據(jù)?集群模式3-多主集群同步數(shù)據(jù)部署
?????????和模式2區(qū)別在于,寫入時可以采用任意的節(jié)點,這樣每個都相當于主節(jié)點
多主集群同步數(shù)據(jù)集群模式4-多主集群轉發(fā)數(shù)據(jù)部署
多主集群轉發(fā)數(shù)據(jù)集群模式5-Master-slave和broke-cluster組合部署?
Master-slave和broke-cluster組合部署??總結:在不同業(yè)務中保證消息高可用有三種方式:消息共享,消息同步,元數(shù)據(jù)共享(大型項目)
高可靠:指的是系統(tǒng)服務長期無故障持續(xù)運行,比如系統(tǒng)突然崩潰等并不影響線上業(yè)務正常運行
實現(xiàn)中間件可靠性:
? ? ? ? a.消息的傳輸:通過協(xié)議保證系統(tǒng)間數(shù)據(jù)解析正確性
? ? ? ? b.消息的存儲:通過持久化來保證消息可靠性
消息中間件優(yōu)勢
? ?a. 異步:消息本身是異步的,它允許在生產(chǎn)者發(fā)送消息很長時間后再由消費者接收消息,而不需要等待響應;如果不用 MQ 的話,只能通過調(diào)用接口的方式進行同步處理.這樣會存在如下問題:一是會阻塞,像我們系統(tǒng)提醒業(yè)務處理過程通常要 1-2 秒,如果一下來了太多請求,可能是處理不過來的,后面的請求只能一直等甚至超時;而 MQ 支持消息堆積,很好解決了這個問題;?二是調(diào)用失敗無法自動重試,MQ 可以很容易實現(xiàn)失敗重試
?? ?b. 解耦:消息隊列減少了消息之間的耦合性,不同的服務之間通過消息隊列通信不需要關心彼此之間的實現(xiàn)細節(jié),只要定義好消息格式即可
?? ??? ?如果用調(diào)用接口方式,調(diào)用三次接口,也不是不可以實現(xiàn).但是如果后期 B 系統(tǒng)說你不需要推送給我了.我這邊是不是需要刪除掉推送給 B 的代碼,這就是代碼耦合了
?? ?c. 廣播:我們只要將消息送到隊列即可,減少聯(lián)調(diào)和開發(fā)的工作量
?? ?d. 流量削峰與流控:當上下游系統(tǒng)處理能力存在差距的時候,利用消息隊列做一個通用的 ”載體”.在下游有能力處理的時候,再進行分發(fā)與處理
消息中間件不足
????a. 系統(tǒng)可用性降低: 如果 MQ 出現(xiàn)問題,就會導致使用到MQ的服務報錯,最終導致系統(tǒng)崩潰
?? ?b. 系統(tǒng)復雜度提高: 加入MQ后,需要考慮如何保證消息的順序性?消息傳遞過程中如何保證不被重復消費?保證消息不會丟失?等等問題
?? ?c. 一致性問題: 比如服務A給服務B、C、D發(fā)送了消息,只有都成功才返回成功;若只有C成功,其他失敗,但是返回成功,這就出現(xiàn)一致性問題
?消息中間件對比?
?????????RabbitMQ: 基于Erlang開發(fā),并發(fā)能力強,微妙級別延時;吞吐量屬于萬級別,稍遜與十萬級別的RockerMQ和Kafaka;更適合并發(fā)量不高的業(yè)務場景
?????????RockerMQ: 阿里基于Java開發(fā)的產(chǎn)品,可以根據(jù)源碼來定制公司的MQ,公司有技術實力我覺得用 RocketMQ 挺好
?????????Kafka? ? ? ? :超高吞吐量,毫秒級延遲,高可用和高可靠,適用于大數(shù)據(jù)領域中的實時計算以及日志采集場景
消息中間件應用場景
1.跨系統(tǒng)進行數(shù)據(jù)的分發(fā)和異步處理,比如發(fā)送郵件、推送短信等
2.高并發(fā)的流量削峰
3.大數(shù)據(jù)分析與傳遞,比如大數(shù)據(jù)領域的實時分析
高并發(fā)流量削峰示意圖總結
以上是生活随笔為你收集整理的分布式中间件之消息中间件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试办公工具推荐-桌面日历
- 下一篇: jpg如何压缩?jpg图片压缩大小怎么改