1. 程式人生 > 其它 >RabbitMQ的四種交換機型別

RabbitMQ的四種交換機型別

前言

這是相關技能的詳解系列,是將東西整理歸納總結,系列的進行記錄與分享,這種方式更有完善性,更能成體系的學習一個技能,方便我們掌握他,這也是我們這種系列的目標,希望在跟著學習瞭解完這個系列後,就能將其吸收為自己的東西。並且為後續的繼續深入,打下一個基礎。

後續我也將更多的將以前零散的東西整理成多個不同的系列,有序的完善整體的知識樹。與大家共同學習共同成長

話不多說,下面進入正文

RabbitMQ是什麼

什麼是訊息中介軟體

訊息中介軟體是基於佇列與訊息傳遞技術,在網路環境中為應用系統提供同步或非同步以及可靠的訊息傳輸的支撐性軟體系統,

一般在系統開發中,常用於將程式解藕,非同步,在分散式環境下擴充套件程序間的通訊等。MQ典型應用場景例如:

  • 非同步處理。把訊息放入訊息中介軟體中,等到需要的時候再去處理。
  • 流量削峰。例如秒殺活動,在短時間內訪問量急劇增加,使用訊息佇列,當訊息佇列
    滿了就拒絕響應,跳轉到錯誤頁面,這樣就可以使得系統不會因為超負載而崩潰。
  • 日誌處理
  • 應用解耦。假設某個服務A需要給許多個服務(B、C、D)傳送訊息,當某個服務(例如B)不需要傳送訊息了,服務A需要改程式碼再次部署;當新加入一個服務(服務E)需要服務A的訊息的時候,也需要改程式碼重新部署;另外服務A也要考慮其他服務掛掉,沒有收到訊息怎麼辦?要不要重新發送呢?是不是很麻煩,使用MQ釋出訂閱模式,服務A只生產訊息傳送到MQ,B、C、D從MQ中讀取訊息,需要A的訊息就訂閱,不需要了就取消訂閱,服務A不再操心其他的事情,使用這種方式可以降低服務或者系統之間的耦合。

什麼是AMQP

AMQP,即Advanced Message Queuing Protocol,一個提供統一訊息服務的應用層標準高階訊息佇列協議,是應用層協議的一個開放標準,為面向訊息的中介軟體設計。基於此協議的客戶端與訊息中介軟體可傳遞訊息,並不受客戶端/中介軟體不同產品,不同的開發語言等條件的限制。Erlang中的實現有RabbitMQ等。

所以,總結為一句話就是,AMQP是一個開放的訊息佇列標準協議!,而RabbitMQ就是此協議的一個開源實現,所以RabbitMQ與AMQP的協議中的概念是高度重合的。這在下面講到RabbitMQ的使用時,再詳說。

RabbitMQ是什麼

RabbitMQ是當前最主流的訊息中介軟體之一!RabbitMQ是一個開源的AMQP實現!

RabbitMQ伺服器端用Erlang語言編寫,支援多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支援AJAX。用於在分散式系統中儲存轉發訊息,在易用性、擴充套件性、高可用性等方面表現不俗。

當然RabbitMQ除了實現了AMQP協議外,也同時支援MQTT,STOMP,AMQP1.0,HTTP 和 WebSocket等協議,以滿足不同場景下的使用。具體的可檢視RAbbitMQ官方文件
https://www.rabbitmq.com/protocols.html

 

RabbitMQ 使用與概念

PS: 所有學習都應該以官方文件為準,所有部落格資訊都可能會有滯後性,不準確性。這也是我一直的準則,希望教會大家怎麼看官方文件,怎麼自我學習。
下面要介紹的內容,也可以直接看官方文件:https://www.rabbitmq.com/tutorials/amqp-concepts.html

RabbitMQ作為一個訊息中介軟體,其中設計思路基本都來源於AMQP協議,主要有如下幾個重要的概念:

  • Server:接收客戶端的連線,實現AMQP實體服務。
  • Connection:連線,應用程式與Server的網路連線,TCP連線。
  • Channel:通道,訊息讀寫等操作在通道中進行。客戶端可以建立多個通道,每個通道代表一個會話任務。
  • Message:訊息,應用程式和伺服器之間傳送的資料,訊息可以非常簡單,也可以很複雜。有Properties和Body組成。Properties為外包裝,可以對訊息進行修飾,比如訊息的優先順序、延遲等高階特性;Body就是訊息體內容。
  • Virtual Host:虛擬主機,用於邏輯隔離。一個虛擬主機裡面可以有若干個Exchange和Queue,同一個虛擬主機裡面不能有相同名稱的Exchange或Queue。
  • Exchange:交換器,接收訊息,按照路由規則將訊息路由到一個或者多個佇列。如果路由不到,或者返回給生產者,或者直接丟棄。RabbitMQ常用的交換器常用型別有direct、topic、fanout、headers四種,後面詳細介紹。
  • Binding:繫結,交換器和訊息佇列之間的虛擬連線,繫結中可以包含一個或者多個RoutingKey。
  • RoutingKey:路由鍵,生產者將訊息傳送給交換器的時候,會發送一個RoutingKey,用來指定路由規則,這樣交換器就知道把訊息傳送到哪個佇列。路由鍵通常為一個“.”分割的字串,例如“com.rabbitmq”。
  • Queue:訊息佇列,用來儲存訊息,供消費者消費。

其結構大致如下:

如圖,主要分為三部分:

  • 生產者
  • 消費者
  • 服務端

整個訊息的釋出與消費的流程大致如下:

  1. 生產者client端指定服務端地址以及vhost虛擬主機,連線服務端
  2. 建立連線後,建立Channel通道,設定此通道的屬性。
  3. 通過通道,宣告交換機,佇列,繫結關係,以及相關屬性
  4. 通過通道,傳送Message訊息到Exchange交換機
  5. 交換機通過binding繫結關係與RoutingKey路由鍵,將訊息分發到對應的Queue佇列
  6. 消費者client通過服務端地址以及vhost連線服務端
  7. 建立連線後,建立通道,設定通道屬性
  8. 通過通道,開啟消費者監聽佇列,從佇列中獲取訊息進行消費
  9. 根據是否延遲確認,確認訊息已經被正常消費成功後,訊息從佇列中刪除

Exchange交換機型別

在上述結構中,生產者傳送訊息,並不是直接傳送到佇列的,而是傳送到Exchange交換機,再由交換機分發到相應佇列,沒有匹配到佇列則丟棄訊息。根據Exchange的型別不同,可靈活實現常見的訊息模式。

Exchange交換機共有四種類型:

  • direct
  • fanout
  • topic
  • headers

direct

Direct,完全匹配型交換機,此種類型交換機,通過RoutingKey路由鍵將交換機和佇列進行繫結, 訊息被髮送到exchange時,需要根據訊息的RoutingKey,來進行匹配,只將訊息傳送到完全匹配到此RoutingKey的佇列。

如圖,不同的key繫結不同的佇列,實現不同訊息分發至不同佇列。

PS: 注意同一個key,可以繫結多個queue佇列。如圖中,當匹配到key1時,則會將訊息分發送至queue1和queue2,這樣兩個佇列都會有相同的訊息資料。

fanout

Fanout,扇出型別交換機,此種交換機,會將訊息分發給所有綁定了此交換機的佇列,此時RoutingKey引數無效。

此種方式,最簡單快速,效能最好,因為少了中間的匹配判斷環節。

topic

Topic,主題型別交換機,此種交換機與Direct類似,也是需要通過routingkey路由鍵進行匹配分發,區別在於Topic可以進行模糊匹配,Direct是完全匹配。
Topic中,將routingkey通過"."來分為多個部分,通過如下功能字元來進行匹配:

  • "*":代表一個部分
  • "#":代表一個或多個部分

舉個例子,加入繫結關係如下圖:

然後傳送一條資訊,routingkey為"a.b.c.d",那麼根據"."將這個路由鍵分為了4個部分,此條路由鍵,將會匹配:

  • a.b.c. :成功匹配,因為可以代表一個部分
  • a.b.# :成功匹配,因為#可以代表一個或多個部分
  • a..c.. : 成功匹配,因為第一和第三部分分別為a和c,且為4個部分,剛好匹配
  • .d : 成功匹配,因為最後一個部分為d,前面所有部分被#代表了

PS:如果繫結的路由鍵為 "#" 時,則接受所有訊息,因為路由鍵所有都匹配

headers

Headers,headers資訊型別交換機,此型別交換機不通過routingkey路由鍵來分發訊息,而是通過訊息內容中的headers屬性來進行匹配。headers型別交換器效能差,在實際中並不常用。

雖然不常用,但也可以瞭解一下其,此種交換機不通過routingkey,但是通過headers進行繫結,也就是在宣告binding繫結關係時,需要傳入需要匹配的header的key/value鍵值對。

如圖,繫結關係中,需要指定"x-match"匹配型別:

  • all:需要所有的key-value都匹配,才能匹配成功
  • any:只需要其中一個key-value匹配,就匹配成功

PS: 不常用,此種方式效能比較差,如果要使用此種方式,使用前可進行效能測試,確保符合業務場景的需求