「消息隊列」是在消息的傳輸過程當中保存消息的容器。算法
「消息」是在兩臺計算機間傳送的數據單位。消息能夠很是簡單,例如只包含文本字符串;也能夠更復雜,可能包含嵌入對象。緩存
消息被髮送到隊列中。「消息隊列」是在消息的傳輸過程當中保存消息的容器。消息隊列管理器在將消息從它的源中繼到它的目標時充當中間人。隊列的主要目的是提供路由並保證消息的傳遞;若是發送消息時接收者不可用,消息隊列會保留消息,直到能夠成功地傳遞它。安全
通常的消息隊列是基於生產者-消費者模型。用於實時性要求並非那麼高、異步通訊的場景。服務器
AMQP(AdvancedMessageQueuingProtocal,高級消息隊列協議)是一個提供統一異步消息傳遞服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件而設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不一樣產品、不一樣開發語言等條件的限制。架構
左邊的客戶端向右邊的客戶發送消息,流程以下:異步
在該模型中,三個主要功能模塊鏈接成一個處理鏈完成預期的功能:ui
Exchange自己不保持消息,只是起到路由的做用,Exchange接收消息生產者(MessageProducer)發送的消息根據不一樣的路由算法將消息發送往MessageQueue。MessageQueue會在消息不能被正常消費時緩存這些消息,具體的緩存策略由實現者決定,當MessageQueue與消息消費者(Messageconsumer)之間的鏈接通暢時,MessageQueue會將消息轉發到consumer。spa
一個Broker(AMQP服務器)中會存在多個MessageQueue?Exchange怎樣知道它要把消息發送到哪一個MessageQueue中去呢?圖8-1中的Binding就是經過綁定Exchange與MessageQueue來解決這個問題。消息應用者(ClientApplication)控制Exchange與某個特定MessageQueue綁定,並將這個MessageQueue接受何種特定消息的條件綁定到Exchange,這個條件也叫Bindingkey或Criteria。AMQP協議的架構以下圖示意。設計
該圖(VirtualHost)用來指Exchange和MessageQueue組成的集合。它是一個虛擬概念,一個虛擬主機能夠是一臺服務器,還能夠是由多臺服務器組成的集羣,還能夠是一些虛擬機組成的集羣,上面運行一些Exchange和MessageQueue。
下面詳細解釋一下AMQP的工做原理:3d
從上圖看,Message是AMQP所操縱的基本單位,它由Producer產生,通過Broker被Consumer所消費。它的基本結構有兩部分:Header和Body。Header是由Producer添加上的各類屬性的集合,這些屬性有:控制Message是否可被緩存,接收的Queue是哪一個,優先級是多少等。Body是真正須要傳送的數據,它是對Broker不可見的二進制數據流,在傳輸過程當中不該該受到影響。
一個Exchange在與多個MessageQueue經過綁定後,Exchange中就會存在一個路由表,這個表中存儲着每一個MessageQueue所須要消息的限制條件。Exchange就會檢查它接收到的每一個Message的Header及Body信息,來決定將Message路由到哪一個Queue中去。每一個Message的Header中應該有個屬性叫RoutingKey,它由Message發送者產生,提供給Exchange路由這條信息的標準。Exchange根據不一樣路由算法有不一樣有ExchangeType。
這些基礎的路由算法由AMQP提供,固然ClientApplication也能夠自定義各類本身的擴展路由算法。
當Exchange按照必定的路由算法把消息發到MessageQueue後,做爲消息的存儲和分發實體,MessageQueue會把消息緩存到內存或硬盤中,而且按照順序把這些消息發給一個或者多個消息的消費者。
OpenStack遵循這樣的設計原則:項目之間經過RESTful API進行通訊;項目內部,不一樣服務進程之間的通訊,則必需要經過消息總線。這種設計思想保證了各個項目對外提供服務的接口能夠被不一樣類型的客戶端高效支持,同時也保證了項目內部通訊接口的可擴展性和可靠性,以支持大規模的部署。
軟件從最初的面向過程,面向對象,再到面向服務(SOA),要求咱們去考慮各個服務之間如何傳遞消息。借鑑硬件總線的概念,消息總線的模式被引入,顧名思義,一些服務向總線發送消息,其餘服務從總線上獲取消息。
OpenStack oslo.messageing庫實現瞭如下兩種方式來完成項目內部各服務進程之間的通訊:
經過遠程過程調用,一個服務進程能夠調用其餘遠程服務進程方法,而且有兩種調用方式:call和cast。call 則是同步執行的,調用者會被阻塞直到結果返回;cast 則是異步執行,結果不會馬上被返回,調用者也不會被阻塞,可是調用者須要利用其餘方式查詢此次遠程調用的結果。
某個服務進程能夠把事件通知發送到消息總線上,該消息總線上全部對此類事件感興趣的服務進程,均可以得到此事件通知並進行一步的處理,處理的結果並不會返回給事件發送者。這種通訊方式,不但能夠在同一個項目內部的各個服務進程之間發送通知,也能夠實現跨項目之間的通知發送。Ceilometer就經過這種方式大量獲取其餘OpenStack項目的事件通知,從而進行計量和監控。
OpenStack中所支持的消息總線類型中,大部分都是基於AMQP的。前面已經提到過了,故不贅述。
配圖解釋:
對於MQ中的概念進行了簡單的介紹。以後還會進行必定的擴充——好比在一些常見應用中MQ的應用。