1.什麼是消息中間件?前端
消息(Message)是指在應用間傳送的數據。這些數據能夠爲文本字符、JSON串、或者內嵌對象。安全
消息中間件(Message Queue Middleware,簡稱MQ)是指利用高效可靠的消息傳遞機制來進行平臺間的通訊,經過數據通訊來達成分佈式系統的集成。服務器
2.消息中間件的傳遞模型網絡
2.1.點對點(P2P,Point-To-Point)模式多線程
2.2.發佈/訂閱(Pub/Sub)模式架構
2.消息中間件的做用併發
2.1.解耦:好比購買商品,下單完成後緊接着須要物流發貨,若是這兩個流程放在同一個系統會形成業務邏輯鏈特長,這時就會考慮將下單和物流發貨設計成兩個服務,服務間經過接口或者消息中間間來進行通訊,以下圖所示。異步
2.2.冗餘(存儲):消息中間件具備消息持久化的能力,若是消費端速度趕不上生產者發送消息的速度,這時消息能夠被持久化到中間件的服務上,等待消費者慢慢消費,生產者端不會阻塞,加大了系統吞吐量。分佈式
另外若是消費者服務端宕機,因爲消息中間件具備消息堆積能力,生產者端仍然能夠將消息發送給中間件,不會受到任何影響,等消費者服務重啓後,這時能夠再從中間件獲取消息消費。高併發
最後MQ爲了保證消息的可靠性,防止消息丟失,消息中間件提供了消息確認機制,只有消費端明確給MQ發送消息成功消費的訊號後,MQ纔會刪除該消息。在未接收到消費訊號前,會一直存儲在MQ上。
2.3.流量削峯:最多見的是在秒殺場景中,用戶購買商品完整的流程可能包含:下單、扣庫存、發短信、發紅包、物流配送,若是整個流程在一個事務或者說線程中執行完,那執行時間是很長的,再加上在秒殺高併發的場景下,服務器壓力大,這個時間可能更長。如何優化?消息中間件,以下圖所示:
加入消息中間件後,下單完成後,該事務內只須要在發送四條消息分別給庫存服務,短信服務,紅包服務,物流服務,而後就能夠給客戶端響應了,這樣減短了整個事務鏈的長度,增長了系統吞吐量。
2.4.可恢復性:當平臺一部分服務失效時,不會影響到整個系統。消息中間件下降了進程間的耦合度,因此即便一個處理消息的進程掛掉,加入消息中間件中的消息仍然能夠在系統恢復後進行處理。
2.5.緩衝:因爲MQ有消息堆積能力,在生產端和消費端之間的MQ服務就能夠做爲緩衝層來下降消費端的壓力,好比在秒殺場景中,給前端服務加入MQ後,高併發的請求過來後只須要將請求轉化爲消息投遞到MQ後,就能夠響應信息了,而消費者這邊能夠按照自己服務器的負載能力去消息隊列中獲取消息消費。
2.6.異步通訊:在不少時候應用不想也不須要當即處理消息,消息中間件提供了異步處理機制,容許應用把消息投遞到中間件中,而後消費端在須要的時候慢慢處理。
3.RabbitMQ簡介
RabbitMQ是採用Erlang語言實現AMQP(Advance Message Queuing Protocol,高級消息隊列協議)協議的消息中間件,它最初起源於金融系統,用於在分佈式系統中轉發消息。
4.RabbitMQ的特色
4.RabbitMQ相關概念
RbbitMQ總體上市一個生產者和消費者模型,主要負責接收消息、存儲消息、轉發消息。
RabbitMQ的總體模型架構如圖所示:
Message:消息,消息通常包含兩個部分:消息體(Payload)和標籤(Label)。在實際應用中,消息體通常是一個帶有業務邏輯結構的數據,好比Json字符串,固然也能夠進一步對消息體進行序列化。消息的標籤是用來表述這條消息的,好比一個交換器名稱和一個路由鍵。
Producer:生產者,就是投遞消息的一方。生產者建立消息,而後發佈到RabbitMQ中。
Consumer:消費者,就是接收消息的一方。
Broker:消息中間件的服務節點。對於RabbitMQ來講,一個RabbitMQ Broker能夠看做一個RabbitMQ服務節點或者服務實例。大多數狀況下也能夠將一個RabbitMQ Broker看做一臺RabbitMQ服務器。
Queue:隊列,是RabbitMQ的內部對象,用於存儲消息。RabbitMQ中的全部消息都只能存儲在隊列中,這一點跟Kafka這種消息中間件相反,Kafka將消息存儲在topic(主題)這個邏輯層面,而相對應的隊列邏輯只是topic實際存儲文件中的位移標識。
RabbitMQ的生產者生產消息並經過交換機和路由鍵最終投遞到隊列中,消費者能夠從隊列中獲取消息並消費。多個消費者能夠訂閱同一個隊列,這時隊列中的消息會被平均分攤(Round-Robin,即輪訓)給多個消費者進行處理,而不是每一個消息都收到全部的消息。
RabbitMQ不支持隊列層面的廣播消費,若是須要廣播消費,須要進行二次開發。
Exchange:交換器。它是用來接收生產者傳遞的消息,而後經過指定的路由鍵將消息路由到對應的一個或多個隊列中,若是路由不到,或許會返回給生產者,或者直接丟棄。
RabbitMQ中的交換器有四種類型,不一樣的類型有着不一樣的路由策略。四種協議分別爲:fanout、direct、topic、headers。AMQP協議裏還提到另外兩種類型:System和自定義,這裏不予描述。
RoutingKey:路由鍵。生產者將消息發送給交換器的時候,通常會指定一個RoutingKey,用來指定這個消息的路由規則。
Binding:綁定。RabbitMQ中經過路由鍵將交換器與隊列關聯起來,而後將他們綁定在一塊兒,Binding就是將他們綁定在一塊兒的路由規則。
Connection:網絡鏈接,好比一個TCP鏈接。客戶端(生產者和消費者)和服務端(RabbitMQ Broker)建立網絡鏈接Connection,基於Connection進行通訊。
Channel:信道,多路複用鏈接中的一個單獨的雙向通訊數據流通道。信道是創建在真實的TCP鏈接內地虛擬鏈接,AMQP 命令都是經過信道發出去的,不論是發佈消息、訂閱隊列仍是接收消息,這些動做都是經過信道完成。由於對於操做系統來講創建和銷燬 TCP 都是很是昂貴的開銷,因此引入了信道的概念,以複用一條 TCP 鏈接。
Connection能夠用來建立多個Channel實例,可是Channel實例不能在線程間共享,應用程序應該爲每一個線程開闢一個Channel。多線程共享Channel實例是非線程安全的。
Virtual Host:虛擬主機。每個RabbitMQ服務器都能建立虛擬的消息服務器,咱們稱之爲虛擬主機(Virtual Host),簡稱vhost。每個vhost本質上是一個獨立小型RabbitMQ服務器,擁有本身獨立的隊列、交換器及綁定關係等,而且它擁有本身獨立的權限。vhost就像是虛擬機與物理服務器同樣,它們在各個實例減提供邏輯上的分離。,爲不一樣程序安全保密的運行數據,它既能將同一個RabbitMQ中的衆多客戶區分開,又能夠避免隊列和交換器等命名衝突。Vhost之間是絕對隔離的。若是在使用RabbitMQ達到必定規模的時候,建議用戶對業務功能、場景進行歸類區分,併爲之分配獨立的vhost。RabbitMQ默認建立的vhost爲「/」。
5.AMQP協議介紹
RabbitMQ是AMQP協議的Erlang實現,固然RabbitMQ還支持STOMP、MQTT等協議,因此RabbitMQ的模型架構和AMQP協議是同樣的。生產者(Producer)將消息(Message)發送給交換器(Exchange),交換器和隊列(Queue)經過綁定建(BingingKey)綁定,當生產者發送消息時所攜帶的路由鍵(RoutingKey)和綁定鍵相匹配時,消息即被存入相應的隊列之中,消費者能夠訂閱相應的隊列來獲取消息。
上面提到的RabbitMQ中的交換器、交換器類型、綁定、路由鍵等都是遵循AMQP協議中相應的概念。
AMQP協議自己包含三層。
AMQP協議是一個通信協議,是應用層的協議,AMQP是經過協議命令進行交互的。