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的反智商設計,這設計的不實用又真廢腦啊。