RabbitMQ 入門系列:5、基礎編碼:交換機的進階介紹及編碼方式。
系列目錄
RabbitMQ 入門系列:1、MQ的應用場景的選擇與RabbitMQ安裝。
RabbitMQ 入門系列:2、基礎含義:鏈接、通道、隊列、交換機。
RabbitMQ 入門系列:3、基礎含義:持久化、排它性、自動刪除、強制性、路由鍵。
RabbitMQ 入門系列:4、基礎編碼:官方SDK使用:鏈接創建、單例改造、發送消息、接收消息。
RabbitMQ 入門系列:5、基礎編碼:交換機的進階介紹及編碼方式。
RabbitMQ 入門系列:6、保障消息:不丟失:發送方、Rabbit存儲端、接收方。
RabbitMQ 入門系列:7、保障消息:不重複消費:產生消息的唯一ID。
RabbitMQ 入門系列:8、擴展內容:接收資訊時:可否根據RoutingKey過濾監聽資訊,答案是不能。
RabbitMQ 入門系列:9、擴展內容:死信隊列:真不適合當延時隊列。
RabbitMQ 入門系列:10、擴展內容:延時隊列:延時隊列插件及其有限的適用場景。
前言:
本篇介紹交換機的進階介紹及編碼方式。
1、 交換機的類型:
在第二篇文時,曾簡單介紹過交換機,但沒太深入,那是為了避免入門阻礙太多。
本篇再稍為加深一下交換機的介紹,但也是點到為止:
交換機默認有4個類型:
direct:1條資訊僅允許發送到1個隊列。(RoutingKey匹配隊列名)
fanout:1條資訊發送到所有綁定的隊列。(忽略RoutingKey)
header:1條資訊發送到匹配的隊隊。(用header頭部數據匹配)
topic:1條資訊發送到匹配RoutingKey規則的隊列。(一般用#和*通配符)
通配符號#(無視.點號)和*(遇到.點號則中止)說明:
topic.#那麼這個隊列會接收topic開頭的消息,如topic.hello.world
topic.*那麼這個隊列只接收topic開頭後面一個的消息,如topic.hello

1、交換機:direct類型及其使用編碼
實際上,之前的介紹中,在使用的程式碼中都避開了交換機。
其實不是沒用到,只是用到的是默認交換機(AMQP default):
1、它是direct類型,因此RoutingKey匹配隊列名。
2、它默認通向所有的隊列,即綁定了所有的隊列。
3、交換機名稱傳值時默認傳空值。
下面進行1個簡單的消息發送:
channel.BasicPublish(「」, 「first", false, null, Encoding.UTF8.GetBytes("這是要發送的內容aaa"));

從Web控制中心查看數據,可以看到,路由使用了默認的,而RoutingKey 則是對應了隊列了名稱。
3、交換機:fanout類型的使用編碼
對fanout類型的使用,所有的routekey都傳空值即可。
using (var channel = Rabbit.Instance.DefaultConnection.CreateModel())
{
//定義隊列
channel.QueueDeclare("user.order");
channel.QueueDeclare("user.birth");
//定義交換機
channel.ExchangeDeclare("user", "fanout");
//交換機綁定2個隊列
channel.QueueBind("user.order", "user", "");
channel.QueueBind("user.birth", "user", "");
//發送到交換機,直接到達2個隊列
channel.BasicPublish("user", "", false, null, Encoding.UTF8.GetBytes("兩個隊列都收到資訊"));
}
管理介面可以看到資訊:

4、交換機:topic類型編碼
對於交換機類型來說:
direct類型:隊列名就是routing key。
fanout類型:只關注交換機名稱,routing key都是空。
topic類型:只有這個是重心放在routing key,而不關心隊列起名規則。
下在看程式碼(用first、first2、first3)來演示(演示前會清空數據):
using (var channel = Rabbit.Instance.DefaultConnection.CreateModel())
{
//定義交換機
channel.ExchangeDeclare("user_topic", "topic");
//交換機綁定3個隊列
channel.QueueBind("first", "user_topic", "#.order");
channel.QueueBind("first2", "user_topic", "#.birth");
channel.QueueBind("first3", "user_topic", "#.birth");
//發送到交換機,直接到達2個隊列
channel.BasicPublish("user_topic", "user.order", false, null, Encoding.UTF8.GetBytes("1隊列都收到資訊"));
channel.BasicPublish("user_topic", "user.birth", false, null, Encoding.UTF8.GetBytes("2隊列都收到資訊"));
}
數據結果:

這裡必須吐槽一下,這個規則的設計反智商啊:
這種設計,用topic模組,一個資訊只能發送到一個隊列:
泥媒,這真是妥委的direct加強版,還真是只能到一個隊列,加了個匹配規則,變成一個很弱雞的功能。
要同時滿足發送到多個隊列,就必須綁定多個綁定規則......
個人覺得設計應該反過來才對:
綁定交換機時,定義完整的路徑,發布消息時,帶上通配符,去匹配規則,達到可以發送一個或多個隊列去才合理。
5、交換機:header類型及其使用編碼
這個類型不常用,暫未想到應用場景,暫不介紹。
總結:
本篇介紹如交換機介紹及以使用其發送消息到多個隊列,特別是topic的路由key的反智商設計,這設計的不實用又真廢腦啊。