消息隊列中間件是分佈式系統中重要的組件,主要解決應用解耦,異步消息,流量削鋒等問題,實現高性能,高可用,可伸縮和最終一致性架構。目前使用較多的消息隊列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。消息中間件到底該如何使用,什麼時候使用這是一個問題,胡亂地使用消息中間件增長了系統的複雜度,若是用很差消息中間件還不如不用。前端
點對點方式是最爲傳統和常見的通信方式,它支持一對1、一對多、多對多、多對一等多種配置方式,支持樹狀、網狀等多種拓撲結構。數據庫
MQ適用於不一樣類型的應用。其中重要的,也是正在發展中的是"多點廣播"應用,即可以將消息發送到多個目標站點(DestinationList)。可使用一條MQ指令將單一消息發送到多個目標站點,並確保爲每一站點可靠地提供信息。MQ不只提供了多點廣播的功能,並且還擁有智能消息分發功能,在將一條消息發送到同一系統上的多個用戶時,MQ將消息的一個複製版本和該系統上接收者的名單發送到目標MQ系統。目標MQ系統在本地複製這些消息,並將它們發送到名單上的隊列,從而儘量減小網絡的傳輸量。安全
發佈/訂閱功能使消息的分發能夠突破目的隊列地理指向的限制,使消息按照特定的主題甚至內容進行分發,用戶或應用程序能夠根據主題或內容接收到所須要的消息。發佈/訂閱功能使得發送者和接收者之間的耦合關係變得更爲鬆散,發送者沒必要關心接收者的目的地址,而接收者也沒必要關心消息的發送地址,而只是根據消息的主題進行消息的收發。在MQ家族產品中,MQEventBroker是專門用於使用發佈/訂閱技術進行數據通信的產品,它支持基於隊列和直接基於TCP/IP兩種方式的發佈和訂閱。服務器
爲了簡化點對點通信模式中的系統配置,MQ提供Cluster(羣集)的解決方案。羣集相似於一個域(Domain),羣集內部的隊列管理器之間通信時,不須要兩兩之間創建消息通道,而是採用羣集(Cluster)通道與其它成員通信,從而大大簡化了系統配置。此外,羣集中的隊列管理器之間可以自動進行負載均衡,當某一隊列管理器出現故障時,其它隊列管理器能夠接管它的工做,從而大大提升系統的高可靠性。網絡
過去幾年中,咱們一直在使用、構建和宣傳消息隊列,咱們認爲它們是很使人敬畏的,這也不是什麼祕密。咱們相信對任何架構或應用來講,消息隊列都是一個相當重要的組件,下面是十個理由:架構
在項目啓動之初來預測未來項目會碰到什麼需求,是極其困難的。消息隊列在處理過程當中間插入了一個隱含的、基於數據的接口層,兩邊的處理過程都要實現這一接口。這容許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵照一樣的接口約束。併發
有時在處理數據的時候處理過程會失敗。除非數據被持久化,不然將永遠丟失。消息隊列把數據進行持久化直到它們已經被徹底處理,經過這一方式規避了數據丟失風險。在被許多消息隊列所採用的"插入-獲取-刪除"範式中,在把一個消息從隊列中刪除以前,須要你的處理過程明確的指出該消息已經被處理完畢,確保你的數據被安全的保存直到你使用完畢。負載均衡
由於消息隊列解耦了你的處理過程,因此增大消息入隊和處理的頻率是很容易的;只要另外增長處理過程便可。不須要改變代碼、不須要調節參數。擴展就像調大電力按鈕同樣簡單。less
當你的應用上了Hacker News的首頁,你將發現訪問流量攀升到一個不一樣尋常的水平。在訪問量劇增的狀況下,你的應用仍然須要繼續發揮做用,可是這樣的突發流量並不常見;若是爲以能處理這類峯值訪問爲標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列可以使關鍵組件頂住增加的訪問壓力,而不是由於超出負荷的請求而徹底崩潰。請查看咱們關於峯值處理能力的博客文章瞭解更多此方面的信息。異步
當體系的一部分組件失效,不會影響到整個系統。消息隊列下降了進程間的耦合度,因此即便一個處理消息的進程掛掉,加入隊列中的消息仍然能夠在系統恢復後被處理。而這種容許重試或者延後處理請求的能力一般是造就一個略感不便的用戶和一個沮喪透頂的用戶之間的區別。
消息隊列提供的冗餘機制保證了消息能被實際的處理,只要一個進程讀取了該隊列便可。在此基礎上,IronMQ提供了一個"只送達一次"保證。不管有多少進程在從隊列中領取數據,每個消息只能被處理一次。這之因此成爲可能,是由於獲取一個消息只是"預約"了這個消息,暫時把它移出了隊列。除非客戶端明確的表示已經處理完了這個消息,不然這個消息會被放回隊列中去,在一段可配置的時間以後可再次被處理。
在許多狀況下,數據處理的順序都很重要。消息隊列原本就是排序的,而且能保證數據會按照特定的順序來處理。IronMO保證消息漿糊經過FIFO(先進先出)的順序來處理,所以消息在隊列中的位置就是從隊列中檢索他們的位置。
在任何重要的系統中,都會有須要不一樣的處理時間的元素。例如,加載一張圖片比應用過濾器花費更少的時間。消息隊列經過一個緩衝層來幫助任務最高效率的執行–寫入隊列的處理會盡量的快速,而不受從隊列讀的預備處理的約束。該緩衝有助於控制和優化數據流通過系統的速度。
在一個分佈式系統裏,要獲得一個關於用戶操做會用多長時間及其緣由的整體印象,是個巨大的挑戰。消息系列經過消息被處理的頻率,來方便的輔助肯定那些表現不佳的處理過程或領域,這些地方的數據流都不夠優化。
不少時候,你不想也不須要當即處理消息。消息隊列提供了異步處理機制,容許你把一個消息放入隊列,但並不當即處理它。你想向隊列中放入多少消息就放多少,而後在你樂意的時候再去處理它們。
如下介紹消息隊列在實際應用中經常使用的使用場景。異步處理,應用解耦,流量削鋒和消息通信四個場景。
異步處理
如下介紹消息隊列在實際應用中經常使用的使用場景。異步處理,應用解耦,流量削鋒和消息通信四個場景。
場景說明: 用戶註冊後,須要發註冊郵件和註冊短信。傳統的作法有兩種 1.串行的方式;2.並行方式.
假設三個業務節點每一個使用50毫秒鐘,不考慮網絡等其餘開銷,則串行方式的時間是150毫秒,並行的時間多是100毫秒。
由於CPU在單位時間內處理的請求數是必定的,假設CPU1秒內吞吐量是100次。則串行方式1秒內CPU可處理的請求量是7次(1000/150)。並行方式處理的請求量是10次(1000/100)
小結:如以上案例描述,傳統的方式系統的性能(併發量,吞吐量,響應時間)會有瓶頸。如何解決這個問題呢?
引入消息隊列,將不是必須的業務邏輯,異步處理。改造後的架構以下:
應用解耦
如何解決以上問題呢?引入應用消息隊列後的方案,以下圖:
流量削鋒
流量削鋒也是消息隊列中的經常使用場景,通常在秒殺或團搶活動中使用普遍。應用場景:秒殺活動,通常會由於流量過大,致使流量暴增,應用掛掉。爲解決這個問題,通常須要在應用前端加入消息隊列。
a、能夠控制活動的人數
b、能夠緩解短期內高流量壓垮應用
用戶的請求,服務器接收後,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接拋棄用戶請求或跳轉到錯誤頁面。
秒殺業務根據消息隊列中的請求信息,再作後續處理
日誌處理
日誌處理是指將消息隊列用在日誌處理中,好比Kafka的應用,解決大量日誌傳輸的問題。架構簡化以下
日誌採集客戶端,負責日誌數據採集,定時寫受寫入Kafka隊列
Kafka消息隊列,負責日誌數據的接收,存儲和轉發
日誌處理應用:訂閱並消費kafka隊列中的日誌數據
消息通信
消息通信是指,消息隊列通常都內置了高效的通訊機制,所以也能夠用在純的消息通信。好比實現點對點消息隊列,或者聊天室等
點對點通信:
客戶端A和客戶端B使用同一隊列,進行消息通信。
聊天室通信:
客戶端A,客戶端B,客戶端N訂閱同一主題,進行消息發佈和接收。實現相似聊天室效果。
以上實際是消息隊列的兩種消息模式,點對點或發佈訂閱模式。模型爲示意圖,供參考。
電商系統
消息隊列採用高可用,可持久化的消息中間件。好比Active MQ,Rabbit MQ,Rocket Mq。
日誌收集系統
分爲Zookeeper註冊中心,日誌收集客戶端,Kafka集羣和Storm集羣(OtherApp)四部分組成。
如下是新浪kafka日誌處理應用案例:
歡迎你們關注我新開通的公衆號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裏面更新,整理的資料也會放在裏面。
以爲寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!