RabbitMQ (二) 簡單佇列
阿新 • • 發佈:2020-12-15
參考:https://blog.csdn.net/vbirdbest/article/details/78583480
簡單佇列的模型:
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}"); } } } }
執行結果:
下面對一些方法的部分引數做下解釋:
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可以重量級訊息佇列),如果都用這種方式去使用的話就真是殺雞用宰牛刀了。
BasicGet
- queue: QueueName, //佇列名稱
- autoAck: true //應答模式,true:自動應答,即消費者獲取到訊息,該訊息就會從佇列中刪除掉,false:手動應答,當從佇列中取出訊息後,需要程式設計師手動呼叫方法應答,如果沒有應答,該訊息會一直存在佇列中.
參考:https://blog.csdn.net/vbirdbest/article/details/78583480