Message Queue
1 什么是MQ
MQ(message queue),本質是個隊列,FIFO 先入先出,只不過隊列中存放的內容是message
而已,同時是一種跨進程的通信機制,用于上下游傳遞消息。
在互聯網架構中,MQ 是一種非常常見的上下游“邏輯解耦+物理解耦”的消息通信服務。使用了 MQ 之后,消息發送上游只需要依賴 MQ,不用依賴其他服務。
2 為什么要使用MQ
流量消峰
舉個例子,如果訂單系統最多能處理一萬次訂單,這個處理能力應付正常時段的下單時綽綽有余,正常時段我們下單一秒后就能返回結果。
但是在高峰期,如果有兩萬次下單操作系統是處理不了的,只能限制訂單超過一萬后不允許用戶下單。
使用消息隊列做緩沖,我們可以取消這個限制,把一秒內下的訂單分散成一段時間來處理,這時有些用戶可能在下單十幾秒后才能收到下單成功的操作,但是比不能下單的體驗要好。
應用解耦
以電商應用為例,應用中有訂單系統、庫存系統、物流系統、支付系統。用戶創建訂單后,如果耦合調用庫存系統、物流系統、支付系統,任何一個子系統出了故障,都會造成下單操作異常。
當轉變成基于消息隊列的方式后,系統間調用的問題會減少很多,比如物流系統因為發生故障,需要幾分鐘來修復。在這幾分鐘的時間里,物流系統要處理的內存被緩存在消息隊列中,用戶的下單操作可以正常完成。當物流系統恢復后,繼續處理訂單信息即可,中單用戶感受不到物流系統的故障,提升系統的可用性。
異步處理
有些服務間調用是異步的,例如 A 調用 B,B 需要花費很長時間執行,但是 A 需要知道 B 什么時候可以執行完,以前一般有兩種方式,A 過一段時間去調用 B 的查詢 api 查詢。或者 A 提供一個 callback api,B 執行完之后調用 api 通知 A 服務。
這兩種方式都不是很優雅,使用消息總線,可以很方便解決這個問題,A 調用 B 服務后,只需要監聽 B 處理完成的消息,當 B 處理完成后,會發送一條消息給 MQ,MQ 會將此消息轉發給 A 服務。這樣 A 服務既不用循環調用 B 的查詢 api,也不用提供 callback api。
同樣 B 服務也不用做這些操作。A 服務還能及時的得到異步處理成功的消息。
Rabbit MQ
Rabbit MQ
是一個在 AMQP(高級消息隊列協議)基礎上完成的,可復用的企業消息系統,是當前最主流的消息中間件之一。功能比較完備,健壯、穩定、易用、跨平臺、支持多種語言
Rabbit MQ
中有幾個比較核心的概念:
- 生產:產生數據發送消息的程序是生產者
- 交換機:一方面它接收來自生產者的消息,另一方面它將消息推送到隊列中。交換機類型將會決定交換機是將消息推送到特定隊列還是推送到多個隊列,亦或者是把消息丟棄。
- 隊列:隊列是 RabbitMQ 內部使用的一種數據結構,本質上是一個大的消息緩沖區。隊列僅受主機的內存和磁盤限制的約束。許多生產者可以將消息發送到一個隊列,許多消費者可以嘗試從一個隊列接收數據。
- 消費者:消費與接收具有相似的含義,大多時候是一個等待接收消息的程序。同一個應用程序中既可以有生產者也可以有消費者。
Rabbit MQ中的工作原理
Broker(交換機):接收和分發消息的應用,RabbitMQ Server就是 Message Broker
Virtual host:出于多租戶和安全因素設計,把AMQP
的基本組件劃分到一個虛擬的分組中,類似于網絡中的namespace
概念。當多個不同的用戶使用同一個RabbitMQ server
提供的服務時,可以劃分出多個vhost
,每個用戶在自己的vhost
創建 exchange/queue
等
Connection:publisher
/consumer
和broker
之間的 TCP 連接
Channel:Channel 是在 connection 內部建立的邏輯連接,如果應用程序支持多線程,通常每個 thread 創建單獨的 channel 進行通訊,AMQP method 包含了 channel id 幫助客戶端和 message broker 識別 channel,所以 channel 之間是完全隔離的。Channel作為輕量級的Connection 極大減少了操作系統建立 TCP connection 的開銷
Exchange:message
到達broker
的第一站。根據分發規則,匹配查詢表中的routing key
,分發消息到queue
中去。常用的類型有:direct (point-to-point), topic (publish-subscribe) and fanout(multicast)
Queue:消息最終被送到這里等待 consumer 取走
Binding:exchange 和 queue 之間的虛擬連接,binding 中可以包含 routing key,Binding 信息被保存到 exchange 中的查詢表中,用于 message 的分發依據