上一節(jié)我們對消息中間件和RabbitMQ本身有了大致印象,本節(jié)主要介紹RabbitMQ的模型架構(gòu)。
相關概念介紹
- 生產(chǎn)者和消費者
Producer: 生產(chǎn)者,投遞消息的一方,消息一般包括兩個部分:消息體(payload)和標簽(label).標簽用來描述消息,比如交換器的名稱和路由鍵
Consumer: 消費者,接手消息的一方.
Broker: 消息中間件的服務節(jié)點 - 隊列
Queue: 隊列
RabbitMQ的消息都存儲在隊列中,多個消費者可以訂閱同一個隊列,這時隊列中的消息會被平均分攤,既輪詢.RabbitMQ不支持廣播消費,也不建議這么做 - 交換器、路由鍵、綁定
Exchange: 交換器
生產(chǎn)者將消息發(fā)送到Exchange,由交換器將消息路由到一個或多個隊列中.如果路由不到,就丟棄或返還給生產(chǎn)者.
Routingkey: 路由鍵
生產(chǎn)者將消息發(fā)送給交換器時,會指定一個路由鍵RoutingKey,用來指定這個消息的路由規(guī)則,而這個RoutingKey需要與交換器類型和綁定鍵(BindingKey)同時使用才會生效.
Binding: 綁定
通過綁定將隊列和交換器關聯(lián)起來,綁定時一般指定一個綁定鍵(BindingKey),這樣在生產(chǎn)者發(fā)送消息時就能找到隊列了. - 交換器類型
RabbitMQ常用的交換器類型有fanout、direct、topic、headers四種。AMQP協(xié)議中還提到另外兩種類型:System和自定義
- fanout: 把所有發(fā)送到該交換器的消息路由到所有與該交換器綁定的隊列中.這是一種類似廣播的發(fā)送方式.上面說RabbitMQ不支持廣播的消息消費,是指從隊列到消費者不支持廣播.不要混淆.
- direct: 按指定的RoutingKey規(guī)則將消息發(fā)送到對應BindingKey的隊列中,這里的RoutingKey需要完全匹配
- topic: 有相對復雜的匹配規(guī)則,如下:
- RoutingKey為一個由
.分隔的字符串,被.分隔的每一段字符串稱為一個單詞,如"com.pctf.routing1" - BindingKey 和 RoutingKey一樣是由
.分隔的字符串 - BindingKey中可以存在兩種特殊字符串
*和#,用于模糊匹配.其中*用于匹配一個單詞,#用于匹配0+個單詞
以下圖為例;
配圖1
- headers: 不依賴路由鍵的匹配規(guī)則來路由消息,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進行匹配
RabbitMQ中Connection與Channel的關系
無論是生產(chǎn)者還是消費者,都需要與RabbitMQ的Broker進行連接,每個連接都是一條tcp連接.也就是connection.一旦tcp連接建立起來,客戶端就可以創(chuàng)建一個AMQP信道,即channel,每個channel都會被指派一個唯一id.信道是建立在channel之上的虛擬連接.
為什么要引入信道:如果對于每個線程,都建立tcp連接,對于操作系統(tǒng)而言,開銷過于昂貴.RabbitMQ使用類似NIO的做法,將tcp連接復用.
每個線程把持一個信道,信道復用了tcp的連接.同時RabbitMQ可以保證每個線程的私密性.就像擁有獨立連接一樣.當每個信道流量不是很大時,復用連接可以有效節(jié)省tcp連接資源.然而當信道本身流量很大時,多個信道復用一個connection就會產(chǎn)生性能瓶頸.進而使整體的流量被限制.這時需要開辟多個connection.將信道分攤到這些connection中.
