目錄
本系列向大家介紹RabbitMQ的簡單用法;
1. RabbitMQ的簡單實踐
2. RabbitMQ的輪詢模式和公平分發
3. RabbitMQ的發布訂閱模式(Publish/Subscribe)
4. RabbitMQ路由模式(Routing)
5. RabbitMQ的主題(Topic)模式
一、Routing模式簡介
RabbitMQ的路由模式,可以簡單理解為,根據exchange綁定的key,將消息路由到不同的queue,模型圖如下:

上圖中幾個關鍵點:
Publisher:消息的生產者
Exchange:路由,類型為direct
Queue:隊列,存儲消息的地方
Consumer:消費者
二、生產者發送消息
生產者不直接直接發送消息到隊列的,只發送到相應的exchange上,代碼如下:
static string EXCHANGE_NAME = "routing_exchange_direct";
static void RoutingPublisher()
{
var conn = RabbitMQHelper.GetConnection();
var channel = conn.CreateModel();
channel.ExchangeDeclare(exchange: EXCHANGE_NAME,type:ExchangeType.Direct);
string routingKey = "error";
var msg = $"hello routing {routingKey}!";
var body = Encoding.UTF8.GetBytes(msg);
channel.BasicPublish(exchange: EXCHANGE_NAME, routingKey: routingKey, basicProperties: null, body: body);
Console.WriteLine($"消息:{msg} ,發送完成!");
channel.Close();
conn.Close();
}
發送成功,圖如下:

我們去rabbitmq的管理頁面,可以看到消息已經發送成功,但是還沒有消費者綁定到這個exchange上:

三、消費者
要消費routing類型的消息,消費者需要綁定自己需要的路由鍵(rountingKey),一個消費者可以綁定多個key
3.1 路由鍵為error的消費者1,代碼如下:
static string EXCHANGE_NAME = "routing_exchange_direct";
static string QUEUE_NAME = "routing_queue_direct1";
static void RoutingConsumer1()
{
var conn = RabbitMQHelper.GetConnection();
var channel = conn.CreateModel();
channel.ExchangeDeclare(exchange: EXCHANGE_NAME, type: ExchangeType.Direct);
channel.QueueDeclare(queue: QUEUE_NAME);
// 綁定routingKey
string routingKey = "error";
channel.QueueBind(queue: QUEUE_NAME, exchange: EXCHANGE_NAME, routingKey: routingKey);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body.ToArray());
Console.WriteLine($"routing Consumer1 收到消息: {message},時間:{DateTime.Now}");
};
channel.BasicConsume(queue: QUEUE_NAME, autoAck: true, consumer: consumer);
Console.ReadKey();
channel.Close();
conn.Close();
}
3.2 路由鍵為error、info、warning的消費者2,代碼如下:
static string EXCHANGE_NAME = "routing_exchange_direct";
static string QUEUE_NAME = "routing_queue_direct2";
static void RoutingConsumer2()
{
var conn = RabbitMQHelper.GetConnection();
var channel = conn.CreateModel();
channel.ExchangeDeclare(exchange: EXCHANGE_NAME, type: ExchangeType.Direct);
channel.QueueDeclare(queue: QUEUE_NAME);
string routingKeyInfo = "info";
string routingKeyError = "error";
string routingKeyWarning = "warning";
// 可以綁定多個routingKey
channel.QueueBind(queue: QUEUE_NAME, exchange: EXCHANGE_NAME, routingKey: routingKeyInfo);
channel.QueueBind(queue: QUEUE_NAME, exchange: EXCHANGE_NAME, routingKey: routingKeyError);
channel.QueueBind(queue: QUEUE_NAME, exchange: EXCHANGE_NAME, routingKey: routingKeyWarning);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body.ToArray());
Console.WriteLine($"routing Consumer2 收到消息: {message},時間:{DateTime.Now}");
};
channel.BasicConsume(queue: QUEUE_NAME, autoAck: true, consumer: consumer);
Console.ReadKey();
channel.Close();
conn.Close();
}
3.4 測試發送不同routingkey的消息
(1) 啟動兩個消費者后,我們可以看到一共有四個key綁定到交換機上;
消費者1的隊列(routing_queue_direct2)綁定了一個key:error,消費者2的隊列(routing_queue_direct2)綁定了三個key:error、info、warning

(2)發送一個rountingKey為error的消息,再發送一個rountingKey為info的消息,我們查看客戶端接收消息的情況:
消費者1只接收到了一條消息,圖如下:

消費者2兩條消息都接收到了,圖如下:

至此,我們的Routing模式已經驗證完畢。
四、小結
1、Routing模式需要綁定到交換機,類型為direct
2、routingKey為分發消息的依據,生產者發送消息時要指定routingKey;消費者可以綁定多個routingKey;
參考資料:https://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html
