1. 程式人生 > 實用技巧 >RabbitMQ (二) 簡單佇列

RabbitMQ (二) 簡單佇列

參考: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