RabbitMQ原理介紹

RabbitMQ歷史

RabbitMQ消息系統是一個由erlang開發的AMQP(Advanced Message Queue )的開源實現。在同步消息通信的世界裏有不少公開標準(如COBAR的IIOP,或者是SOAP等),可是在異步消息處理中卻不是這樣,只有大企業有一些商業實現(如微軟的MSMQ ,IBM的Websphere MQ等),所以,在2006年的6月,Cisco 、Redhat、iMatix 等聯合制定了AMQP的公開標準。安全

RabbitMQ是由RabbitMQ Technologies Ltd開發而且提供商業支持的。該公司在2010年4月被SpringSource(VMWare的一個部門)收購。在2013年5月被併入Pivotal。其實VMWare,Pivotal和EMC本質上是一家的。不一樣的是VMWare是獨立上市子公司,而Pivotal是整合了EMC的某些資源,如今並無上市。服務器

RabbitMQ能爲你作些什麼?

言歸正傳,RabbitMQ,或者說AMQP解決了什麼問題,或者說它的應用場景是什麼?併發

消息系統容許軟件應用相互鏈接和擴展,這些應用能夠相互連接起來組成一個更大的應用,或者將用戶設備和數據進行鏈接。消息系統經過將消息的發送和接收分離來實現應用程序的異步和解偶。或許你正在考慮進行數據投遞,非阻塞操做或推送通知。或許你想要實現發佈/訂閱,異步處理,或者工做隊列。全部這些都屬於消息系統的模式。RabbitMQ是一個消息代理,一個消息系統的媒介。它能夠爲你的應用提供一個通用的消息發送和接收平臺,而且保證消息再傳輸過程當中的安全。異步

對於一個大型的軟件系統來講,它會有不少的組件或者說模塊或者說子系統。那麼這些模塊的如何通訊?這和傳統的IPC有很大的區別。傳統的IPC不少都是在單一系統上的,模塊耦合性很大,不適合擴展(Scalability);若是使用socket那麼不一樣的模塊的確能夠部署到不一樣的機器上,可是仍是有不少問題須要解決。好比:socket

1)信息的發送者和接收者如何維持這個鏈接,若是一方的鏈接中斷,這期間的數據如何方式丟失?高併發

2)如何下降發送者和接收者的耦合度?工具

3)如何讓Priority高的接收者先接到數據?性能

4)如何作到load balance?有效均衡接收者的負載?測試

5)如何有效的將數據發送到相關的接收者?也就是說將接收者subscribe 不一樣的數據,如何作有效的filter。spa

6)如何作到可擴展,甚至將這個通訊模塊發到cluster上?

7)如何保證接收者接收到了完整,正確的數據?

AMDQ協議解決了以上的問題,而RabbitMQ實現了AMQP。

Rabbitmq工做模式

RabbitMQ原理介紹(一)

如上圖:

RabbitMQ Server

是一種傳輸服務,它的角色就是維護一條從Producer(生產者)到Consumer(消費者)的路線,保證數據可以按照指定的方式進行傳輸。可是這個保證也不是100%的保證,可是對於普通的應用來講這已經足夠了。固然對於商業系統來講,能夠再作一層數據一致性的防禦,就能夠完全保證系統的一致性了。

Client A & B

也叫Producer(生產者),就是數據的發送方。一個Message(消息)有兩個部分:payload(有效載荷)和label(標籤)。payload顧名思義就是傳輸的數據。label是exchange的名字或者說是一個tag,它描述了payload,並且RabbitMQ也是經過這個label來決定把這個Message發給哪一個Consumer(消費者)。AMQP僅僅描述了label,而RabbitMQ決定了如何使用這個label的規則。

Client 1 & 2 & 3

也叫Consumer(消費者),就是數據的接收方。把queue(隊列)比做是一個有名字的郵箱,當有Message到達某個郵箱後,RabbitMQ把它發送給它的某個訂閱者即Consumer。固然可能會把同一個Message發送給不少的Consumer。在這個Message中,只有payload,label已經被刪掉了。對於Consumer來講,它是不知道誰發送的這個信息的。就是協議自己不支持。可是固然了若是Producer發送的payload包含了Producer的信息就另當別論了。

對於一個數據從Producer到Consumer的正確傳遞,還有三個概念須要明確:exchanges, queues and bindings。

Exchanges – 是生產者發佈消息的通道。

Queue – 是消費者接受消息的通道。

Bindings – 是將消息從交換路由綁定到特定隊列中的。

還有幾個概念是上述圖中沒有標明的,那就是Connection(鏈接),Channel(通道,頻道)。

Connection – 就是一個TCP的鏈接,Producer和Consumer都是經過TCP鏈接到RabbitMQ Server的。之後咱們能夠看到,程序的起始處就是創建這個TCP鏈接。

Channels – 虛擬鏈接,它創建在上述的TCP鏈接中。數據流動都是在Channel中進行的。也就是說,通常狀況是程序起始創建TCP鏈接,第二步就是創建這個Channel。

那麼,爲何使用Channel,而不是直接使用TCP鏈接?

對於OS來講,創建和關閉TCP鏈接是有代價的,頻繁的創建關閉TCP鏈接對於系統的性能有很大的影響,並且TCP的鏈接數也有限制,這也限制了系統處理高併發的能力。可是,在TCP鏈接中創建Channel是沒有上述代價的。對於Producer或者Consumer來講,能夠併發的使用多個Channel進行Publish或者Receive。有實驗代表,1s的數據能夠Publish10K的數據包。固然對於不一樣的硬件環境,不一樣的數據包大小這個數據確定不同,可是我只想說明,對於普通的Consumer或者Producer來講,這已經足夠了。若是不夠用,你考慮的應該是如何細化split你的設計。

Rabbitmq技術亮點

1)可靠性

RabbitMQ提供了多種技術可讓你在性能和可靠性之間進行權衡。這些技術包括持久性、投遞確認、發佈者證明和高可用性。

2)靈活的路由

消息在到達隊列前是經過交換機進行路由的。RabbitMQ爲典型的路由邏輯提供了多種內置交換機類型。若是你有更復雜的路由需求,能夠將這些交換機組合起來使用,甚至你能夠寫本身的交換機類型,而且當作RabbitMQ的插件來使用。

3)集羣

在相同局域網中的多個RabbitMQ服務器能夠被聚合在一塊兒,做爲一個獨立的邏輯代理來使用。

4)聯合

對於服務器來講,它比集羣須要更多的鬆散和非可靠連接。爲此RabbitMQ提供了聯合模型。

5)高可用的隊列

在同一個集羣中,隊列能夠被鏡像到多個機器中,以確保當其中某些硬件出現事故後,你的消息仍然是安全的。

6)多協議

RabbitMQ 支持多種消息協議中的消息傳遞。

7)普遍的客戶端

只要是你能想到的語言幾乎都有與其相適配的RabbitMQ客戶端。

8)可視化管理工具

RabbitMQ附帶了一個易於使用的可視化管理工具,它能夠幫助你監控消息代理的每個環節。

9)追蹤

若是你的消息系統有異常行爲,RabbitMQ還提供了追蹤的支持,讓你可以發現問題所在。

10)插件系統

RabbitMQ附帶了各類各樣的插件來對本身進行擴展。甚至你也能夠寫本身的插件來使用。

11)還有什麼呢…

商業支持

能夠提供商業支持,包括培訓和諮詢。

大型社區

圍繞着RabbitMQ有一個大型的社區,在那兒產生了各類各樣的客戶端、插件、指南等等。

關於RabbitMQ

RabbitMQ是使用Erlang開發的一個消息隊列,能夠構建成集羣,也能夠單獨使用。

根據測試,RabbitMQ在不使用ACK機制的,Msg大小爲1K的狀況下,QPS可達6W+。再雙方ACK機制,Msg大小爲1K的狀況下,QPS瞬間降到了1W+。從某種意義上RabbitMQ還真是慢,可是咱們須要思考下。

  1. 咱們真的每一個消息都能到1K嗎?
  2. 咱們真的須要雙方都對消息ACK的系統嗎?

好了,若是兩個回答都是YES,那麼RabbitMQ就是慢的。若是是No,那麼RabbitMQ仍是一個很是快的隊列。

RabbitMQ慢有幾個緣由?

  1. RabbitMQ作爲一個Broker,不僅僅作到了簡單的數據轉發功能,還保證了單個隊列上的數據有序,即使是有多個消費者和多個生產者。
  2. RabbitMQ的策略是實時轉發,而不像Kafka那樣等待刷盤以後才讓消費者來消費。
  3. 若是消費者和生產者不對等,會產生大量的磁盤IO操做,進行消息換出。

RabbitMQ爲何很差用?

  1. AMQP協議自己比較複雜,參數比較多。
  2. Erlang寫的,不少人不熟悉,而且Mnesia出現問題好多人解決不了。

RabbitMQ該怎麼用?

  1. RabbitMQ的消息應當儘量的小,而且只用來處理實時且要高可靠性的消息。
  2. 消費者和生產者的能力盡可能對等,不然消息堆積會嚴重影響RabbitMQ的性能。
  3. 集羣部署,使用熱備,保證消息的可靠性。

RabbitMQ 中文文檔

http://rabbitmq.mr-ping.com/

相關文章
相關標籤/搜索