基本概念
- 消息(message): 消息就是指在應用與應用之間傳輸的數據。消息可以很簡單,比如一個字符串;消息也可以很復雜,比如一個對象。消息包括消息體(即實際數據)和路由鍵(可以理解成標簽),后面會 一 一 介紹。
- 生產者(producer):發(fā)送消息的程序。
- 消費者(consumer):接收并處理消息的程序。
-
服務節(jié)點(Broker):也就是RabbitMQ服務器。
消息隊列運轉過程圖解:生產者將消息先序列化,然后指定交換機和路由鍵,最后將消息發(fā)送到Rabbit MQ;消費者從Rabbit MQ訂閱相應的隊列,得到消息后先反序列化,然后對消息數據進行處理。 -
隊列:是RabbitMQ中的內部對象,用于存儲消息,且Rabbit MQ的消息只能存儲在隊列中;和數據結構中的隊列一個意思,先進先出,如下圖。
隊列,用來存儲消息
生產者將消息發(fā)送到隊列,多個消費者可以訂閱同一個隊列進行消息消費,這時消息是被平均分攤給多個消費者處理,如下圖。
上圖顯示生產者直接將消息投遞到隊列,實際上不是這樣的,而是生產者先將消息投遞到交換器,再由交換機路由到對應的隊列中,這里就又涉及到幾個概念,路由鍵(Routing Key)、綁定鍵(Binding Key)、交換器(Exchange)。 - 交換器(Exchange):可以想成生產者和隊列之間的一個中間人,消費者將消息給交換器,交換器通過一定的規(guī)則將消息轉發(fā)給對應的隊列,這個規(guī)則由RoutingKey、BindingKey、交換器類型共同決定。
- 路由鍵(Routing Key):生產者將消息發(fā)送給交換器時,一般會指定一個RoutingKey,用來指定這個消息的路由規(guī)則,而這個RoutingKey需要與交換器、BingingKey聯(lián)合使用才會生效。
-
綁定鍵(BindingKey):將交換器和隊列進行綁定關聯(lián),這樣交換器就知道如何路由消息到隊列。
三者關系圖示,交換器根據RoutingKey和BingingKey確定將消息路由到哪個隊列
交換器類型
是的,交換器也有類型。RabbitMQ中常用交換器分為四種類型,fanout、direct、topic、headers四種,下面 一 一 介紹。
fanout:它會將所有發(fā)送到該交換器的消息路由到所有與該交換器綁定的隊列中,而與RoutingKey、BindingKey無關。
-
direct:它會把消息路由到RoutingKey和BindingKey完全匹配的隊列中,如下圖。
如果生產者投遞消息時指定的RoutingKey是error,則消息會被交換器路由到Queue1和Queue2;如果RoutingKey是error或debug,則消息會被路由到Queue2;如果是其他的路由鍵,則消息不會被路由到這兩個隊列中。 -
topic:前面的direct是嚴格匹配的,有些時候并不能滿足實際業(yè)務需求,topic類型的交換器對此進行了擴展,約定使用由“ . ”分割的字符串來指定RoutingKey和BindingKey,如com.rabbitmq.client、java.lang,而且可以使用通配符“ * ”和“ # ”做模糊匹配,“ * ”用來匹配一個單詞,“ # ”用來匹配多個單詞,如下圖。
當路由鍵為 com.rabbitmq.client 時,消息會被路由到Queue1和Queue2; 當路由鍵為 com.hidden.client 時,消息會被路由到Queue2;當路由鍵為 com.hidden.demo 時,消息會被路由到Queue2;當路由鍵為 java.rabbitmq.demo 時,消息會被路由到Queue1;當路由鍵為 com.czy.abc 時,消息會被路由到Queue2和Queue3;當路由鍵為java.util.concurrent 時,消息會被丟棄會返回給生產者,因為它沒有匹配到任何BindingKey. headers:headers類型的交換器不依賴RoutingKey和RoutingKey的匹配規(guī)則來路由消息,而是根據發(fā)送消息內容中的headers屬性進行匹配。headers類型的交換器性能很差,不實用,基本看不到它的存在,就不細講了。
有了以上概念,可以得到RabbitMQ模型架構

RabbitMQ模型架構
注意事項:其實可以將RoutingKey和BindingKey看成是一個東西,實際用的時候不會去特別區(qū)分他倆的關系。





