RabbitMQ六种队列模式-主题模式
前言
RabbitMQ六種隊列模式-簡單隊列
RabbitMQ六種隊列模式-工作隊列
RabbitMQ六種隊列模式-發(fā)布訂閱
RabbitMQ六種隊列模式-路由模式
RabbitMQ六種隊列模式-主題模式 [本文]
從前面的幾篇我們依次經(jīng)歷了 exchange 模式從 fanout > direct 的轉(zhuǎn)變過程,在 fanout 時,我們只能進行簡單的廣播,對應(yīng)類型比較單一,使用 direct 后,消費者則可以進行一定程度的選擇,但是,direct 還是有局限性,路由不支持多個條件。
怎么講呢?
direct 不支持匹配 routingKey,一但綁定了就是綁定了,而 topic 主題模式支持規(guī)則匹配,只要符合 routingKey 就能發(fā)送到綁定的隊列上。
文章目錄
- 前言
- 1. 什么是主題模式
- 2. 代碼部分
- 2.1 生產(chǎn)者
- 2.2 *消費者
- 2.3 #消費者
- 2.4 運行截圖
- 3. 總結(jié)
1. 什么是主題模式
官方鏈接:http://www.rabbitmq.com/tutorials/tutorial-five-java.html
topics 主題模式跟 routing 路由模式類似,只不過路由模式是指定固定的路由鍵 routingKey,而主題模式是可以模糊匹配路由鍵 routingKey,類似于SQL中 = 和 like 的關(guān)系。
P 表示為生產(chǎn)者、 X 表示交換機、C1C2 表示為消費者,紅色表示隊列。
topics 模式與 routing 模式比較相近,topics 模式不能具有任意的 routingKey,必須由
一個英文句點號“.”分隔的字符串(我們將被句點號“.”分隔開的每一段獨立的字符串稱為一個單詞),比如 “l(fā)azy.orange.fox”。topics routingKey 中可以存在兩種特殊字符“”與“#”,用于做模糊匹配,其中“”用于匹配一個單詞,“#”用于匹配多個單詞(可以是零個)。
“*” 表示任何一個詞
“#” 表示0或1個詞
以上圖中的配置為例:
如果一個消息的 routingKey 設(shè)置為 “xxx.orange.rabbit”,那么該消息會同時路由到 Q1 與 Q2,routingKey="lazy.orange.fox”的消息會路由到Q1與Q2;
routingKey="lazy.brown.fox”的消息會路由到 Q2;
routingKey="lazy.pink.rabbit”的消息會路由到 Q2(只會投遞給Q2一次,雖然這個routingKey 與 Q2 的兩個 bindingKey 都匹配);
routingKey="quick.brown.fox”、routingKey="orange”、routingKey="quick.orange.male.rabbit”的消息將會被丟棄,因為它們沒有匹配任何bindingKey。
接下來代碼為例:
2. 代碼部分
2.1 生產(chǎn)者
public class ProducerTopic {private static final String EXCHANGE_NAME = "my_topic_exchange";public static void main(String[] args) throws IOException, TimeoutException {/** 1.創(chuàng)建新的連接 */Connection connection = MQConnectionUtils.newConnection();/** 2.創(chuàng)建通道 */Channel channel = connection.createChannel();/** 3.綁定的交換機 參數(shù)1交互機名稱 參數(shù)2 exchange類型 */channel.exchangeDeclare(EXCHANGE_NAME, "topic");/** 4.發(fā)送消息 */String routingKey = "log.info.error";String msg = "topic_exchange_msg:" + routingKey;System.out.println("[send] = " + msg);channel.basicPublish(EXCHANGE_NAME, routingKey, null, msg.getBytes());/** 5.關(guān)閉通道、連接 */channel.close();connection.close();/** 注意:如果消費沒有綁定交換機和隊列,則消息會丟失 */} }2.2 *消費者
public class ConsumerLogXTopic {private static final String QUEUE_NAME = "topic_consumer_info";private static final String EXCHANGE_NAME = "my_topic_exchange";public static void main(String[] args) throws IOException, TimeoutException {System.out.println("log * 消費者啟動");/* 1.創(chuàng)建新的連接 */Connection connection = MQConnectionUtils.newConnection();/* 2.創(chuàng)建通道 */Channel channel = connection.createChannel();/* 3.消費者關(guān)聯(lián)隊列 */channel.queueDeclare(QUEUE_NAME, false, false, false, null);/* 4.消費者綁定交換機 參數(shù)1 隊列 參數(shù)2交換機 參數(shù)3 routingKey */channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "log.*");DefaultConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {String msg = new String(body, "UTF-8");System.out.println("消費者獲取生產(chǎn)者消息:" + msg);}};/* 5.消費者監(jiān)聽隊列消息 */channel.basicConsume(QUEUE_NAME, true, consumer);}}2.3 #消費者
public class ConsumerLogJTopic {private static final String QUEUE_NAME = "topic_consumer_info";private static final String EXCHANGE_NAME = "my_topic_exchange";public static void main(String[] args) throws IOException, TimeoutException {System.out.println("log # 消費者啟動");/* 1.創(chuàng)建新的連接 */Connection connection = MQConnectionUtils.newConnection();/* 2.創(chuàng)建通道 */Channel channel = connection.createChannel();/* 3.消費者關(guān)聯(lián)隊列 */channel.queueDeclare(QUEUE_NAME, false, false, false, null);/* 4.消費者綁定交換機 參數(shù)1 隊列 參數(shù)2交換機 參數(shù)3 routingKey */channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "log.#");DefaultConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {String msg = new String(body, "UTF-8");System.out.println("消費者獲取生產(chǎn)者消息:" + msg);}};/* 5.消費者監(jiān)聽隊列消息 */channel.basicConsume(QUEUE_NAME, true, consumer);}}2.4 運行截圖
生產(chǎn)者
星花*消費者
#消費者
3. 總結(jié)
1、topic 相對于之前幾種算是比較復(fù)雜了,簡單來說,就是每個隊列都有其關(guān)心的主題,所有的消息都帶有一個“標題”(RouteKey),exchange 會將消息轉(zhuǎn)發(fā)到所有關(guān)注主題能與 routeKey 模糊匹配的隊列。
2、在進行綁定時,要提供一個該隊列關(guān)心的主題,如“#.sscai.#”表示該隊列關(guān)心所有涉及 sscai 的消息(一個 routeKey 為 "club.sscai.tmax”的消息會被轉(zhuǎn)發(fā)到該隊列)。
3、"#”表示0個或若干個關(guān)鍵字,“”表示一個關(guān)鍵字。如“club.”能與“club.sscai”匹配,無法與“club.sscai.xxx”匹配;但是“club.#”能與上述兩者匹配。
4、同樣,如果 exchange 沒有發(fā)現(xiàn)能夠與 routeKey 匹配的 Queue,則會拋棄此消息。
案例代碼:https://www.lanzous.com/i5ydu6d
我創(chuàng)建了一個java相關(guān)的公眾號,用來記錄自己的學(xué)習(xí)之路,感興趣的小伙伴可以關(guān)注一下微信公眾號哈:niceyoo
總結(jié)
以上是生活随笔為你收集整理的RabbitMQ六种队列模式-主题模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++注意事项
- 下一篇: jQuery kxbdMarquee 无