我用2個月的時間破繭成蝶,BAT大廠面試總結
基礎知識
RabbitMQ是一個開源的訊息代理和佇列伺服器,用來通過普通協議在完全不同的應用之間共享資料,它是使用Erlang
語言來編寫的,並且是基於AMQP
協議的;
RabbitMQ高效能的原因
- Erlang語言在交換機的互動方面效能優秀的(
Erlang
語言最初在於交換機領域的架構模式,這樣使得RabbitMQ在Broker之間進行資料互動的效能是非常優秀的) - Erlang有著和原生
Socket
一樣的延遲
AMQP協議
什麼是AMQP高階訊息佇列協議
AMQP(Advanced Message Queueing Protocol)定義:具有現代特徵的二進位制協議。是一個提供統一訊息服務的應用層標準高階訊息佇列協議,是應用層協議的一個開放標準,為面向訊息的中介軟體設計
AMQP協議模型:
Publisher 推送訊息前先與Server建立連線,找到Virtual host
,然後將訊息推送至Exchange交換機。而交換機與Message Queue
有繫結關係(一個交換機相當於一個獨立的虛擬機器,而這個虛擬機器內的各種獨立的應用就相當於一個Queue,這個Queue與交換機繫結),Consumer
通過繫結的對佇列,而交換機也綁定了佇列。傳送者將訊息傳送給交換機,這樣就能完成訊息的推送了
整體架構圖
基本概念
Broker
訊息佇列服務程序,接收客戶端的連線,實現AMQP實體服務。
Connection
連線,應用程式與Broker
的網路連線。
Producer
訊息生產者,即生產方客戶端,生產方客戶端將訊息傳送到MQ。
Consumer
訊息消費者,即消費方客戶端,接收MQ轉發的訊息。
Channel
網路通道,幾乎所有的操作都在Channel
中進行,Channel是進行訊息讀寫的通道。客戶端可建立多個Channel,每個Channel代表一個會話任務
Message
訊息,伺服器和應用程式之間傳送的資料,由Properties
和Body組成。Properties可以對訊息進行修飾,比如訊息的優先順序、延遲等高階特性;Body則就是訊息體內容。
Virtual Host
虛擬地址,用於進行邏輯隔離,最上層的訊息路由。一個Virtual Host裡面可以有若干個Exchange和Queue,同一個Virtual Host
Exchange
交換機,接收訊息,根據路由鍵轉發訊息到繫結的佇列。
常見的有4種不同的交換機型別:
- 直連交換機:Direct exchange
- 扇形交換機:Fanout exchange
- 主題交換機:Topic exchange
- 首部交換機:Headers exchange
扇形交換機
扇形交換機是最基本的交換機型別,扇形交換機會把能接收到的訊息全部發送給繫結在自己身上的佇列。因為廣播不需要思考,所以扇形交換機處理訊息的速度也是所有的交換機型別裡面最快的
直連交換機
直連交換機是一種帶路由功能的交換機,一個佇列會和一個交換機繫結,除此之外再繫結一個routing_key
,當訊息被髮送的時候,需要指定一個binding_key
,這個訊息被送達交換機的時候,就會被這個交換機送到指定的佇列裡面去。同樣的一個binding_key
也是支援應用到多個佇列中的
這樣當一個交換機繫結多個佇列,就會被送到對應的佇列去處理
適用場景:有優先順序的任務,根據任務的優先順序把訊息傳送到對應的佇列,這樣可以指派更多的資源去處理高優先順序的佇列
主題交換機
直連交換機的routing_key
方案非常簡單,如果我們希望一條訊息傳送給多個佇列,那麼這個交換機需要繫結上非常多的routing_key
,假設每個交換機上都繫結一堆的routing_key
連線到各個佇列上。那麼訊息的管理就會異常地困難。
所以RabbitMQ
提供了一種主題交換機,傳送到主題交換機上的訊息需要攜帶指定規則的routing_key
,主題交換機會根據這個規則將資料傳送到對應的(多個)佇列上。
主題交換機的routing_key
需要有一定的規則,交換機和佇列的binding_key
需要採用*.#.*.....
的格式,每個部分用.
分開,其中:
*
表示一個單詞#
表示任意數量(零個或多個)單詞
當一個佇列的繫結鍵為#
的時候,這個佇列將會無視訊息的路由鍵,接收所有的訊息
首部交換機
首部交換機是忽略routing_key
的一種路由方式。路由器和交換機路由的規則是通過Headers
資訊來交換的,這個有點像HTTP
的Headers
。
將一個交換機宣告成首部交換機,繫結一個佇列的時候,定義一個Hash
的資料結構,訊息傳送的時候,會攜帶一組hash資料結構的資訊,當Hash
的內容匹配上的時候,訊息就會被寫入佇列。
繫結交換機和佇列的時候,Hash結構中要求攜帶一個鍵x-match
,這個鍵的Value可以是any或者all,這代表訊息攜帶的Hash是需要全部匹配(all),還是僅匹配一個鍵(any)就可以了
相比直連交換機,首部交換機的優勢是匹配的規則不被限定為字串
- any: 只要在釋出訊息時攜帶的有一對鍵值對headers滿足佇列定義的多個引數
arguments
的其中一個就能匹配上,注意這裡是鍵值對的完全匹配,只匹配到鍵了,值卻不一樣是不行的; - all:在釋出訊息時攜帶的所有
Entry
必須和繫結在佇列上的所有Entry完全匹配
Binding
Exchange和Queue之間的虛擬連線,Exchange在與多個Message Queue發生Binding後會生成一張路由表,路由表中儲存著Message Queue
所需訊息的限制條件即Binding Key。當Exchange收到Message時會解析其Header得到Routing Key,Exchange根據Routing Key與Exchange Type將Message路由到Message Queue。Binding Key由Consumer在Binding Exchange
與Message Queue時指定,而Routing Key由Producer傳送Message時指定,兩者的匹配方式由Exchange Type決定
Routing Key
一個路由規則,虛擬機器可用它來確定如何路由一個特定訊息。
Queue
也稱為Message Queue
,訊息佇列,儲存訊息並將它們轉發給消費者。
訊息釋出流程:
- 生產者和Broker建立TCP連線。
- 生產者和
Broker
建立通道。 - 生產者通過通道訊息傳送給Broker,由Exchange將訊息進行轉發。
- Exchange將訊息轉發到指定的Queue(佇列)
訊息接收流程:
- 消費者和Broker建立TCP連線 。
- 消費者和
Broker
建立通道。 - 消費者監聽指定的Queue(佇列)
- 當有訊息到達Queue時Broker預設將訊息推送給消費者。
- 消費者接收到訊息。
訊息流轉過程
生產者生產出Message並投遞到Exchange
上
一個Exchange可以繫結多個Message Queue
,它根據路由策略(routing key
)路由到指定的佇列,最後由消費端去監聽佇列
工作模式
佇列模式:
對於任務過重或任務較多情況使用工作佇列可以提高任務處理的速度。
1、一條訊息只會被一個消費者接收;
2、rabbitmq採用輪詢的方式將訊息是平均傳送給消費者的;
3、消費者在處理完某條訊息後,才會收到下一條訊息。
釋出訂閱模式:
1、每個消費者監聽自己的佇列。
2、生產者將訊息發給broker
,由交換機將訊息轉發到繫結此交換機的每個佇列,每個繫結交換機的佇列都將接收到訊息
對應交換機中的fanout
型別
路由模式:
1、每個消費者監聽自己的佇列,並且設定routingkey。
2、生產者將訊息發給交換機,由交換機根據routingkey
來轉發訊息到指定的佇列。
對應交換機中的direct
型別
萬用字元模式:
對應交換機中的topics
型別
Header轉發器模式:
對應交換機中的header
型別
遠端過程呼叫模式:
RPC即客戶端遠端呼叫服務端的方法,使用MQ可以實現RPC的非同步呼叫,基於Direct交換機實現,流程如下:
- 客戶端即是生產者就是消費者,向
RPC
請求佇列傳送RPC呼叫訊息,同時監聽RPC響應佇列。 - 服務端監聽RPC請求佇列的訊息,收到訊息後執行服務端的方法,得到方法返回的結果。
- 服務端將RPC方法的結果傳送到
RPC
響應佇列。 - 客戶端(RPC呼叫方)監聽RPC響應佇列,接收到RPC呼叫結果。
總結
大型分散式系統猶如一個生命,系統中各個服務猶如骨骼,其中的資料猶如血液,而Kafka猶如經絡,串聯整個系統。這份Kafka原始碼筆記通過大量的設計圖展示、程式碼分析、示例分享,把Kafka的實現脈絡展示在讀者面前,幫助讀者更好地研讀Kafka程式碼。
需要免費領取這份Kafka原始碼筆記的鐵汁們,麻煩幫忙轉發一下這篇文章+關注我,然後戳這裡免費獲取!