消息队列01
?公司項目里面用到了這個rabbitmq,自己以前不熟悉,看了代碼里面的應用,自己也準備試著搭建下。
?可以參照其他博主的這篇優秀博文:?https://www.cnblogs.com/chengpeng15/p/5814197.html
?
?
一 前期需要了解的概念
1.什么是異步?什么是異步通信?
異步:客戶端不需要等待服務器處理消息,甚至不需要等待消息投遞完成。客戶端發送消息,然后繼續執行。(因為客戶端假定了服務器最終可以收到并處理這條消息)
異步通信是指:有些業務不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許用戶把消息放入隊列,但并不立即處理它。想在隊列中放入多少消息就放多少,然后在需要的時候再去處理他。
?
2.為什么說異步中? 間接性 是關鍵?
一個應用向另一個應用發送消息時,兩個應用間沒有間接的聯系。而是發送方的應用程序會將消息交給一個服務器(也就是消息中間件), 由服務來將消息投遞給接收方。
?
3.建立一個消息隊列的服務器,所有內部的通訊交互都通過消息隊列進行分發與訂閱。
?
?
4.使用消息隊列有以下的好處?:
A. 解耦
消息隊列在處理過程中間插入了一個隱含的、基于數據的接口層,兩邊的處理過程都要實現這一接口。這允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。
B. 冗余
有時在處理數據的時候處理過程會失敗。除非數據被持久化,否則將永遠丟失。消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據丟失風險。在被許多消息隊列所采用的“插入-獲取-刪除”范式中,在把一個消息從隊列中刪除之前,需要你的處理過程明確的指出該消息已經被處理完畢,確保你的數據被安全的保存直到你使用完畢。
C. 擴展性
因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的;只要另外增加處理過程即可。不需要改變代碼、不需要調節參數。擴展就像調大電力按鈕一樣簡單。
D. 靈活性 & 峰值處理能力
在訪問量劇增的情況下,你的應用仍然需要繼續發揮作用,但是這樣的突發流量并不常見;如果為以能處理這類峰值訪問為標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住增長的訪問壓力,而不是因為超出負荷的請求而完全崩潰。
E. 可恢復性
當體系的一部分組件失效,不會影響到整個系統。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復后被處理。而這種允許重試或者延后處理請求的能力通常是造就一個略感不便的用戶和一個沮喪透頂的用戶之間的區別。
F. 送達保證
消息隊列提供的冗余機制保證了消息能被實際的處理,只要一個進程讀取了該隊列即可。無論有多少進程在從隊列中領取數據,每一個消息只能被處理一次。這之所以成為可能,是因為獲取一個消息只是"預定"了這個消息,暫時把它移出了隊列。除非客戶端明確的表示已經處理完了這個消息,否則這個消息會被放回隊列中去,在一段可配置的時間之后可再次被處理。
G.排序保證
在許多情況下,數據處理的順序都很重要。消息隊列本來就是排序的,并且能保證數據會按照特定的順序來處理。消息漿糊通過FIFO(先進先出)的順序來處理,因此消息在隊列中的位置就是從隊列中檢索他們的位置。
H.緩沖
在任何重要的系統中,都會有需要不同的處理時間的元素。例如,加載一張圖片比應用過濾器花費更少的時間。消息隊列通過一個緩沖層來幫助任務最高效率的執行--寫入隊列的處理會盡可能的快速,而不受從隊列讀的預備處理的約束。該緩沖有助于控制和優化數據流經過系統的速度。
I. 理解數據流
在一個分布式系統里,要得到一個關于用戶操作會用多長時間及其原因的總體印象,是個巨大的挑戰。消息系列通過消息被處理的頻率,來方便的輔助確定那些表現不佳的處理過程或領域,這些地方的數據流都不夠優化。
J. 異步通信
很多時候,你不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許你把一個消息放入隊列,但并不立即處理它。你想向隊列中放入多少消息就放多少,然后在你樂意的時候再去處理它們。
?
?
2.MQ原理
2.1mq模型
Pub/Sub發布訂閱(廣播):使用topic作為通信載體?
PTP點對點:使用queue作為通信載體?
2.2 mq的組成
-
Broker:消息服務器,作為server提供消息核心服務
-
Producer:消息生產者,業務的發起方,負責生產消息傳輸給broker
-
Consumer:消息消費者,業務的處理方,負責從broker獲取消息并進行業務邏輯處理
-
Topic:主題,發布訂閱模式下的消息統一匯集地,不同生產者向topic發送消息,由MQ服務器分發到不同的訂閱者,實現消息的廣播
-
Queue:隊列,PTP模式下,特定生產者向特定queue發送消息,消費者訂閱特定的queue完成指定消息的接收
-
Message:消息體,根據不同通信協議定義的固定格式進行編碼的數據包,來封裝業務數據,實現消息的傳輸
2.3 mq常用協議
-
AMQP?
AMQP即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議,?
是應用層協議的一個開放標準,為面向消息的中間件設計。基于此協議的客戶端與消息中間件可傳遞消息,并?
不受客戶端/中間件不同產品,不同開發語言等條件的限制。?
優點:可靠、通用 -
MQTT協議?
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協?
議,有可能成為物聯網的重要組成部分。該協議支持所有平臺,幾乎可以把所有聯網物品和外部連接起來,?
被用來當做傳感器和致動器(比如通過Twitter讓房屋聯網)的通信協議。?
優點:格式簡潔、占用帶寬小、移動端通信、PUSH、嵌入式系統 -
STOMP協議?
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息協議,是一種為MOM(Message Oriented Middleware,面向消息的中間件設計的簡單文本協議。STOMP提供一個可互操作的連接格式,允許客戶端與任意STOMP消息代理(Broker)進行交互。?
優點:命令模式(非topic\queue模式) -
XMPP協議?
XMPP(可擴展消息處理現場協議,Extensible Messaging and Presence Protocol)是基于可擴展標記語言(XML)的協議,多用于即時消息(IM)以及在線現場探測。適用于服務器之間的準即時操作。核心是基于XML流傳輸,這個協議可能最終允許因特網用戶向因特網上的其他任何人發送即時消息,即使其操作系統和瀏覽器不同。?
優點:通用公開、兼容性強、可擴展、安全性高,但XML編碼格式占用帶寬大 -
其他基于TCP/IP自定義的協議?
有些特殊框架(如:redis、kafka、zeroMq等)根據自身需要未嚴格遵循MQ規范,而是基于TCP\IP自行封裝了一套協議,通過網絡socket接口進行傳輸,實現了MQ的功能。
2.4 MQ選型
-
RabbitMQ?
使用Erlang編寫的一個開源的消息隊列,本身支持很多的協議:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它變的非常重量級,更適合于企業級的開發。同時實現了Broker架構,核心思想是生產者不會將消息直接發送給隊列,消息在發送給客戶端時先在中心隊列排隊。對路由(Routing),負載均衡(Load balance)、數據持久化都有很好的支持。多用于進行企業級的ESB整合。 -
ZeroMQ?
又稱?MQ、0MQ、ZMQ,號稱最快的消息隊列系統,專門為高吞吐量、低延遲的場景開發,在金融界的應用中經常使用,偏重于實時數據通信場景。ZMQ能夠實現RabbitMQ不擅長的高級/復雜的隊列,但是開發人員需要自己組合多種技術框架,開發成本高。因此ZeroMQ具有一個獨特的非中間件的模式,更像一個socket library,你不需要安裝和運行一個消息服務器或中間件,因為你的應用程序本身就是使用ZeroMQ API完成邏輯服務的角色。但是ZeroMQ僅提供非持久性的隊列,如果down機,數據將會丟失。如:Twitter的Storm中使用ZeroMQ作為數據流的傳輸。 ZeroMQ套接字是與傳輸層無關的:ZeroMQ套接字對所有傳輸層協議定義了統一的API接口。默認支持 進程內(inproc) ,進程間(IPC) ,多播 ,TCP協議,在不同的協議之間切換只要簡單的改變連接字符串的前綴。可以在任何時候以最小的代價從進程間的本地通信切換到分布式下的TCP通信。ZeroMQ在背后處理連接建立,斷開和重連邏輯。?
特性:-
無鎖的隊列模型?
對于跨線程間的交互(用戶端和session)之間的數據交換通道pipe,采用無鎖的隊列算法CAS;在pipe的兩端注冊有異步事件,在讀或者寫消息到pipe的時,會自動觸發讀寫事件。 -
批量處理的算法?
對于批量的消息,進行了適應性的優化,可以批量的接收和發送消息。 -
多核下的線程綁定,無須CPU切換?
區別于傳統的多線程并發模式,信號量或者臨界區, zeroMQ充分利用多核的優勢,每個核綁定運行一個工作者線程,避免多線程之間的CPU切換開銷。
-
-
ActiveMQ?
Apache下的一個子項目。使用Java完全支持JMS1.1和J2EE 1.4規范的 JMS Provider實現,少量代碼就可以高效地實現高級應用場景。可插拔的傳輸協議支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多種語言客戶端 C++、Java、.Net,、Python、 Php、 Ruby等。 -
Redis?
使用C語言開發的一個Key-Value的NoSQL數據庫,開發維護很活躍,雖然它是一個Key-Value數據庫存儲系統,但它本身支持MQ功能,所以完全可以當做一個輕量級的隊列服務來使用。對于RabbitMQ和Redis的入隊和出隊操作,各執行100萬次,每10萬次記錄一次執行時間。測試數據分為128Bytes、512Bytes、1K和10K四個不同大小的數據。實驗表明:入隊時,當數據比較小時Redis的性能要高于RabbitMQ,而如果數據大小超過了10K,Redis則慢的無法忍受;出隊時,無論數據大小,Redis都表現出非常好的性能,而RabbitMQ的出隊性能則遠低于Redis。 -
Kafka?
Apache下的一個子項目,使用scala實現的一個高性能分布式Publish/Subscribe消息隊列系統,具有以下特性: 快速持久化:通過磁盤順序讀寫與零拷貝機制,可以在O(1)的系統開銷下進行消息持久化;?
高吞吐:在一臺普通的服務器上既可以達到10W/s的吞吐速率;?
高堆積:支持topic下消費者較長時間離線,消息堆積量大;?
完全的分布式系統:Broker、Producer、Consumer都原生自動支持分布式,依賴zookeeper自動實現復雜均衡;?
支持Hadoop數據并行加載:對于像Hadoop的一樣的日志數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。
-
?
?
?
?
?
?
?
?
?
--未完,待補充
轉載于:https://www.cnblogs.com/PinkPink/p/9264007.html
總結
- 上一篇: C++内存模型
- 下一篇: 20180705 考试记录