天天看點

RabbitMQ 進階指南

本文介紹RabbitMQ一些原理

1 RabbitMQ 簡介

1.1 介紹

  RabbitMQ 是一個由 erlang 開發的基于 AMQP(Advanced Message Queue)協定的開源實作。用于在分布式系統中存儲轉發消息,在易用性、擴充性、高可用性等方面都非常的優秀,是目前最主流的消息中間件之一。RabbitMQ 官網:http://www.rabbitmq.com

1.2 AMQP

  AMQP 是應用層協定的一個開放标準,為面向消息的中間件設計。消息中間件主要用于元件之間的解耦,消息的發送者無需知道消息使用者的存在,同樣,消息使用者也不用知道發送者的存在。AMQP 的主要特征是面向消息、隊列、路由(包括點對點和釋出/訂閱)、可靠性、安全。

1.3 系統架構

RabbitMQ 進階指南

消息隊列的使用過程大概如下:

用戶端連接配接到消息隊列伺服器,打開一個 channel;

用戶端聲明一個 exchange,并設定相關屬性;

用戶端聲明一個 queue,并設定相關屬性;

用戶端使用 routing key,在 exchange 和 queue 之間建立好綁定關系;

用戶端投遞消息到 exchange,exchange 接收到消息後,就根據消息的 key 和已經設定的 binding,進行消息路由,将消息投遞到一個或多個隊列裡。

如上圖所示:AMQP 裡主要說兩個元件,Exchange 和 Queue。綠色的X就是 Exchange ,紅色的是 Queue ,這兩者都在 Server 端,又稱作 Broker,這部分是 RabbitMQ 實作的,而藍色的則是用戶端,通常有 Producer 和 Consumer 兩種類型。

1.4 幾個概念

P: 為 Producer,資料的發送方;

C:為 Consumer,資料的接收方;

Exchange:消息交換機,它指定消息按什麼規則,路由到哪個隊列;

Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列;

Binding:綁定,它的作用就是把 exchange 和 queue 按照路由規則綁定起來;

Routing Key:路由關鍵字,exchange 根據這個關鍵字進行消息投遞;

vhost:虛拟主機,一個 broker 裡可以開設多個 vhost,用作不同使用者的權限分離;

channel:消息通道,在用戶端的每個連接配接裡,可建立多個 channel,每個 channel 代表一個會話任務。

4 四種 Exchange 模式

  AMQP 協定中的核心思想就是:生産者和消費者隔離,生産者從不直接将消息發送給隊列。生産者通常不知道是否一個消息會被發送到隊列中,隻是将消息發送到一個交換機。先由 Exchange 來接收,然後 Exchange 按照特定的政策轉發到 Queue 進行存儲。同理,消費者也是如此。Exchange 就類似于一個交換機,轉發各個消息分發到相應的隊列中。

  RabbitMQ 提供了四種 Exchange 模式:fanout、direct、topic、header. 由于 header 模式在實際使用中較少,是以本節隻對前三種模式進行比較。

4.1 Fanout Exchange

RabbitMQ 進階指南

所有發送到 Fanout Exchange 的消息都會被轉發到與該 Exchange 綁定(Binding)的所有 Queue 上。

Fanout Exchange 不需要處理 RouteKey,隻需要簡單的将隊列綁定到 exchange 上,這樣發送到 exchange 的消息都會被轉發到與該交換機綁定的所有隊列上。類似子網廣播,每台子網内的主機都獲得了一份複制的消息。

是以,Fanout Exchange 轉發消息是最快的。

4.2 Direct Exchange

RabbitMQ 進階指南

所有發送到 Direct Exchange 的消息被轉發到 RouteKey 中指定的 Queue.

Direct 模式可以使用 RabbitMQ 自帶的 Exchange:default Exchange ,是以不需要将 Exchange 進行任何綁定(binding)操作 。消息傳遞時,RouteKey 必須完全比對,才會被隊列接收,否則該消息會被抛棄。

4.3 Topic Exchange

RabbitMQ 進階指南

所有發送到 Topic Exchange 的消息被轉發到所有關心 RouteKey 中指定 Topic 的 Queue 上,Exchange 将 RouteKey 和某 Topic 進行模糊比對。此時隊列需要綁定一個 Topic,可以使用通配符進行模糊比對,符号#比對一個或多個詞,符号比對不多不少一個詞。是以log.#能夠比對到log.info.oa,但是log. 隻會比對到log.error.

是以,Topic Exchange 使用非常靈活。

5 RPC 遠端過程調用

  在這一節中,主要講述 RabbitMQ RPC. 其實,RabbitMQ RPC 就是通過消息隊列(Message Queue)來實作 RPC 的功能,就是用戶端向服務端發送定義好的 Queue 消息,其中攜帶的消息就應該是服務端将要調用的方法的參數 ,并使用 Propertis 告訴服務端将結果傳回到指定的 Queue.

5.1 RabbitMQ RPC 的特點

Message Queue 把所有的請求消息存儲起來,然後處理,和用戶端解耦;

Message Queue 引入新的結點,系統的可靠性會受 Message Queue 結點的影響;

Message Queue 是異步單向的消息。發送消息設計成是不需要等待消息處理的完成。

是以對于有同步傳回需求的,Message Queue 是個不錯的方向。

5.2 普通 PRC 的特點

同步調用,對于要等待傳回結果/處理結果的場景,RPC 是可以非常自然直覺的使用方式,當然 RPC 也可以是異步調用;

由于等待結果,用戶端會有線程消耗。

如果以異步 RPC 的方式使用,用戶端線程消耗可以去掉,但不能做到像消息一樣暫存消息請求,壓力會直接傳導到服務端。

5.3 适用場合說明

希望同步得到結果的場合,RPC 合适。

希望使用簡單,則 RPC;RPC 操作基于接口,使用簡單,使用方式模拟本地調用。異步的方式程式設計比較複雜。

不希望用戶端受限于服務端的速度等,可以使用 Message Queue.

5.4 RabbitMQ RPC工作流程

RabbitMQ 進階指南

基本概念:

  Callback queue 回調隊列,用戶端向伺服器發送請求,伺服器端處理請求後,将其處理結果儲存在一個存儲體中。而用戶端為了獲得處理結果,那麼客戶在向伺服器發送請求時,同時發送一個回調隊列位址reply_to.

  Correlation id 關聯辨別,用戶端可能會發送多個請求給伺服器,當伺服器處理完後,用戶端無法辨識在回調隊列中的響應具體和那個請求時對應的。為了處理這種情況,用戶端在發送每個請求時,同時會附帶一個獨有correlation_id屬性,這樣用戶端在回調隊列中根據correlation_id字段的值就可以分辨此響應屬于哪個請求。

流程說明:

  • 當用戶端啟動的時候,它建立一個匿名獨享的回調隊列;
  • 在 RPC 請求中,用戶端發送帶有兩個屬性的消息:一個是設定回調隊列的 reply_to 屬性,另一個是設定唯一值的correlation_id屬性;
  • 将請求發送到一個 rpc_queue 隊列中;
  • 伺服器等待請求發送到這個隊列中來,當請求出現的時候,它執行他的工作并且将帶有執行結果的消息發送給 reply_to 字段指定的隊列;
  • 用戶端等待回調隊列裡的資料。當有消息出現的時候,它會檢查correlation_id屬性,如果此屬性的值與請求比對,将它傳回給應用。