消息發送模式實戰之直接模式與主題模式
1. 前言
Hello,大家好。在前面幾章中,我們重點介紹了 RabbitMQ 的所有基礎知識內容,這些基礎知識內容是入門 RabbitMQ 的關鍵,是后續用好 RabbitMQ 的基礎。
那么,從本章開始呢,作為本套課程的最后一章內容,考慮到同學們的工作應用場景,所以,本章會為同學們介紹一些關于 RabbitMQ 實戰方向的內容,包括但不限于對我們工作中常用功能的優化,以及對程序環境的優化。
本小節作為 RabbitMQ 實戰章節的開篇小節,會首先為同學們介紹之前我們講過的,消息發送模式系列的實戰內容,老師會通過概念加代碼的形式來進行講解。
本節主要內容:
-
直接模式與主題模式基礎概念回顧;
-
直接模式與主題模式代碼實操。
2.直接模式與主題模式基礎概念回顧
從本小節開始,老師會首先為同學們介紹消息發送模式的實戰部分內容,本節會介紹消息發送模式之直接模式與主題模式的實戰內容,在我們正式開始使用代碼進行實戰之前,讓我們先來回顧一下消息發送模式之間接模式與主題模式的基礎概念。
2.1 直接模式基礎概念回顧
定義:
直接模式,即直接發送消息模式,指的是將消息直接發送給消費者。
描述:
直接模式允許將多個隊列綁定到一個交換機上,在生產者發送消息給交換機時,需要攜帶一個 key ,而這個 key 一般被稱為 routing key 或者 binding key,所以直接模式有時也被稱為路由模式。
Tips: RabbitMQ 一般將這個 key 叫做 binding key,但是在實際情況中,出于字面意思,習慣性地將 key 叫做 routing key
直接模式總共分為兩種業務場景,我們先來看第一種業務場景,一般被叫做’單 key 綁定’,如下圖所示:

我們再來看直接模式的最后一個業務場景,多重 key 綁定,如下圖所示:

在圖中我們可以看到,Q1、Q2 兩個隊列,分別綁定到了 routing key 均為 black 的 direct 交換機上,即名稱相同的一個 key 綁定到了多個隊列上面,這種現象被稱為多重 key 綁定。
在多重 key 綁定下,生產者生產的消息均會被發送到相同 key 值所綁定的隊列上面,這里需要同學們注意。
2.2 主題模式基礎概念回顧
定義:
主題模式,也被稱為通配符模式,官網一般稱為主題模式,即交換機與消息隊列所綁定的 key 值可以像匹配通配符的方式,來匹配消息隊列,到底什么意思呢,我們往下看。
描述:

主題模式對 routing key 的匹配規則做了改進,上述其他四種模式中有涉及 key 匹配的地方都是完全匹配,即名稱必須相等時才能把 key 匹配上,而對于主題模式,則不需要這樣。
主題模式將 key 值中的每個單詞或者關鍵詞,使用英文狀態下的 . 符號進行間隔,如上圖所示。
我們這里只是對直接消息發送模式,和主題消息發送模式的基礎概念進行了一個簡單的回顧,如果有同學忘了這些基礎概念,可以回過頭去 《RabbitMQ 消息發送模式詳解》 這一小節復習。
3 直接模式與主題模式代碼實操
3.1 直接模式代碼實操
在上述基礎概念中,我們對直接消息發送模式的兩種基礎業務場景做了介紹,下面會分別用代碼實現這兩種業務場景,實現代碼如下所示(以下均為消費者代碼,生產者請自行實現):
實現代碼:
// 直接模式第一種業務場景
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueBind(QUEUE_ONE, EXCHANGE_NAME, "Routing Key");
channel.close();
connection.close();
代碼解釋:
第 1-5 行,我們使用了 RabbitMQ 的 ConnectionFactory 連接工廠,來初始化了一些獲取 RabbitMQ 連接的必要參數;
第 6 行,我們從 RabbitMQ 的連接工廠中,獲取到了一個 RabbitMQ Conneciton 連接實例;
第 7 行,我們通過 RabbitMQ 連接實例,創建了一個 channel 通道,為之后的消息通信提供媒介;
第 8 行,我們將創建出來的 channel 通道與我們的隊列相綁定,并單獨指定了一個名為 Routing Key 的 key 值。
第 9-10 行,在處理完通道與連接實例之后,我們分別調用了 close 方法,將建立的通信連接和通道進行關閉,以節省資源開銷。
以上代碼是我們實現的直接模式的,第一種業務場景,即單 key 綁定的業務場景,因為我們在 queueBind 方法中,為一個隊列指定了一個單一的 key 值。接下來讓我們看一下第二種業務場景的實現:
實現代碼:
// 直接模式第二種業務場景
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueBind(QUEUE_ONE, EXCHANGE_NAME, "Routing Key");
channel.queueBind(QUEUE_TWO, EXCHANGE_NAME, "Routing Key");
channel.close();
connection.close();
代碼解釋:
第 1-7 行,代碼和第一種業務場景相似,這里不再贅述;
第 8-9 行,我們分別使用 channel 的 queueBind 方法來為兩個不同的隊列,聲明了同樣的 Routing Key 值。
第 10-11 行,代碼和第一種業務場景相似,這里不再贅述;
這里我們重點看第 8-9 行代碼,我們為兩個不同的消息隊里指定了同一個 Routing Key 的值,那么再有消息過來時,同一條消息就會發送到這兩條隊列中,這就是第二種業務場景,即多重 key 綁定業務場景。
3.2 主題模式代碼實操
我們來看主體模式的代碼實現:
實現代碼:
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key.*");
channel.close();
connection.close();
代碼解釋:
第 1-7 行,代碼和第一種業務場景相似,這里不再贅述;
第 8 行,我們使用 channel 的 queueBind 方法來將消息隊列和通道進行綁定,并聲明了名為 key.* 的 Routing Key 值。
第 10-11 行,代碼和第一種業務場景相似,這里不再贅述;
當我們設置了 key.* 的 Routing Key 值之后,我們的消息就會根據這個規則進行匹配的分發,這就是主題模式。
Tips:
1. 我們在實現直接消息發送模式的時候,一定要注意我們的業務場景,key 值的設定一定要符合實際情況;
2. 我們在實現主體消息發送模式的時候,要注意我們 key 值的一個匹配規則,要根據實際需要進行設置,不要隨意設置。
4. 小結

本小節為同學們詳細介紹了 RabbitMQ 消息發送模式之直接模式與主題模式的代碼實操等內容,包括直接模式與主題模式基礎概念等內容的回顧,以及直接模式常見的兩種業務場景的代碼實現、主題模式的代碼實現,同學們需要理清代碼實現的思路和步驟。