RabbitMQ (二) 簡單隊列

參考:https://blog.csdn.net/vbirdbest/article/details/78583480

簡單隊列的模型:

RabbitMQ (二) 簡單隊列

P : 生產者,即 Producer

C : 消費者,即 Consumer

"hello" : 消息

紅色方塊即隊列

首先新建一個工具類,方便獲取連接.

 public static class ConnectionHelper
{
public static IConnection GetConnection()
{
//定義一個連接工廠
ConnectionFactory factory = new ConnectionFactory
{
HostName = "127.0.0.1",//設置服務器地址
Port = 5672, //設置端口號
VirtualHost = "/vhost_refuge",//設置虛擬主機
UserName = "refuge",//設置用戶名
Password = "******"//設置密碼
};
return factory.CreateConnection();
}
}

創建一個生產者

 /// <summary>
/// 生產者
/// /<summary>
public class Producer
{
//定義隊列的名稱
private const string QueueName = "test_simple_queue";
/// <summary>
/// 發送消息
/// /<summary>

public static void Send()
{
//獲取一個連接
using (IConnection connection = ConnectionHelper.GetConnection())
{
//從連接中獲取一個信道
using (IModel channel = connection.CreateModel())
{
//聲明隊列
channel.QueueDeclare
(
queue: QueueName, //隊列名稱
durable: false, //是否持久化
exclusive: false, //是否專屬
autoDelete: false, //是否自動刪除
arguments: null //隊列的配置
);
//創建一個消息
string msg = "hello";
//發送消息
channel.BasicPublish
(
exchange: "", //交換機名稱
routingKey: QueueName, //路由鍵
basicProperties: null, //該條消息的配置
body: Encoding.Default.GetBytes(msg) //消息字節數組
);
Console.WriteLine($"send {msg}");
}
}
}
}

創建一個消費者

 /// <summary>
/// 消費者
/// /<summary>
public class Consumer
{
/// <summary>

/// 隊列名稱
/// /<summary>
private const string QueueName = "test_simple_queue";
/// <summary>
/// 接收消息
/// /<summary>
public static void Receive()
{
//獲取一個連接
using (IConnection connection = ConnectionHelper.GetConnection())
{
//從連接中獲取一個信道
using (IModel channel = connection.CreateModel())
{
           //獲取消息
BasicGetResult res = channel.BasicGet
(
queue: QueueName, //隊列名稱
autoAck: true //是否自動確認
);
if (res == null)
{
return;
}
byte[] bytes = res.Body;
string msg = Encoding.Default.GetString(bytes);
Console.WriteLine($"receive {msg}");
}
}
}
}

運行結果:

RabbitMQ (二) 簡單隊列

下面對一些方法的部分參數做下解釋:

QueueDeclare

  • queue 隊列名稱
  • durable 隊列是否持久化.false:隊列在內存中,服務器掛掉後,隊列就沒了;true:服務器重啟後,隊列將會重新生成.注意:只是隊列持久化,不代表隊列中的消息持久化!!!!
  • exclusive 隊列是否專屬,專屬的範圍針對的是連接,也就是說,一個連接下面的多個信道是可見的.對於其他連接是不可見的.連接斷開後,該隊列會被刪除.注意,不是信道斷開,是連接斷開.並且,就算設置成了持久化,也會刪除.
  • autoDelete 當所有消費者客戶端連接斷開時是否自動刪除隊列.
  • arguments 隊列的參數配置

BasicPublish

  • basicProperties: null, //該條消息的配置
  • body: Encoding.Default.GetBytes(msg) //消息字節數組
  • exchange: "", //交換機名稱
  • routingKey: QueueName, //路由鍵

文章開頭提到的簡單隊列的模型中,沒有交換機,這裡的交換機名稱我們傳入的也是空字符串,

但是,這不代表就沒有使用交換機.

實際上,系統會為每個隊列都隱式的綁定一個默認的交換機,交換機的名稱為“(AMQP default)”,類型為直連接 direct,當你手動創建一個隊列時,後臺會自動將這個隊列綁定到一個名稱為空的Direct類型交換機上,綁定路由名稱與隊列名稱相同,所以這裡雖然沒有顯示聲明交換機,但路由鍵和隊列名稱一樣,所以系統就將消息發送到這個默認的交換機裡。有了這個默認的交換機和綁定,我們就可以像其他輕量級的隊列,如Redis那樣,直接操作隊列來處理消息。不過理論上是可以的,但實際上在RabbitMQ裡直接操作是不可取的。消息始終都是先發送到交換機,由交換級經過路由傳送給隊列,消費者再從隊列中獲取消息的。不過由於這個默認交換機和路由的關係,使我們只關心隊列這一層即可,這個比較適合做一些簡單的應用,畢竟沒有發揮RabbitMQ的最大功能(RabbitMQ可以重量級消息隊列),如果都用這種方式去使用的話就真是殺雞用宰牛刀了。

RabbitMQ (二) 簡單隊列

BasicGet

  • queue: QueueName, //隊列名稱
  • autoAck: true //應答模式,true:自動應答,即消費者獲取到消息,該消息就會從隊列中刪除掉,false:手動應答,當從隊列中取出消息後,需要程序員手動調用方法應答,如果沒有應答,該消息會一直存在隊列中.
參考:https://blog.csdn.net/vbirdbest/article/details/78583480


分享到:


相關文章: