參數中的 arguments
之前講參數的一些作用的時候,忽略了最后一個字典類型的參數,因為這個參數是大有文章的,值得單獨進出來說道說道。
這時,就不得不打開我們的 Web UI管理系統了,可以看到在這邊添加queue的時候,有Arguments下面有一些說明,Message TTL,Auto expire…….
Message TTL
可以看到,點擊一下Message TTL,它的參數名是 x-message-ttl 類型是number,那么這個應該怎么用呢?
一起來看看官方解釋,嗯。。。其實也就是在說,在聲明隊列的時候可以添加這個參數,那么它的作用是讓發布的message在隊列中可以存活多長時間,以毫秒為單位。更通俗點就是,設置了這個參數,發布的消息在queue時間超過了你設定的時間就會被刪除掉。
送上代碼,不多說,先跑起來,這時就可以看到,在features也可以看到queue是ttl的
//聲明一個queue,里面的內容自發布起五秒后被刪除 channel.QueueDeclare("messagettlqueue", true, false, false, new Dictionary<string, object> { { "x-message-ttl", 5000 } });
這個是針對queue的,當然更加定制化的針對message也是有的,也就是說可以讓queue里的某條message在多久消失
var properties = channel.CreateBasicProperties(); //設置過期時間 properties.Expiration = "5000"; channel.BasicPublish(null, "queue", properties, Encoding.UTF8.GetBytes("我五秒后就會消失"));
Auto expire
之前是針對 queue中的消息或者消息本身,而這個才是針對queue,這里是官方解釋,也就是說,當前的queue在指定的時間內,沒有consumer、basic.get也就是未被訪問,就會被刪除。
設置起來也是非常簡單的
//聲明一個queue,queue五秒內而且未被任何形式的消費,則被刪除 channel.QueueDeclare("queue", true, false, false, new Dictionary<string, object> { { "x-expires", 5000 } });
MaxLength與MaxLength bytes
相信到這里大家已經可以根據名字去猜測它的作用了,沒錯它們是設置queue的消息最大條數與消息最大占用大小
並不是說,設置了最大長度為10,第11條數據插入的時候就會報錯,而是在超過了最大長度后進行插入會刪除之前插入的消息為本次的留出空間,也就是說無論什么時候,queue中的消息始終都是十條,相應的最大占用大小也是這個道理,當超過了這個大小的時候,會刪除之前插入的消息為本次的留出空間。
//聲明一個queue,最大長度10,最大大小2048bytes channel.QueueDeclare("queue", true, false, false, new Dictionary<string, object> { { "x-max-length", 10 }, { "x-max-length-bytes", 2048} });
Dead letter exchagne 與 Dead letter routing key
Dead letter 死信,可能有些人對這個詞比較陌生,那么我們首先來了解什么叫死信,也就是說那些沒有被投遞出去的信件

就像上面的messagettl,maxlength等。消息因為超時或超過限制在隊列里消失,這樣我們就丟失了一些消息,也許里面就有一些是我們做需要獲知的。而rabbitmq的死信功能則為我們帶來了解決方案。設置了dead letter exchange與dead letter routingkey(要么都設定,要么都不設定)那些因為超時或超出限制而被刪除的消息會被推動到我們設置的exchange中,再根據routingkey推到queue中

這里是consumer端,聲明了一個testqueue,它里面的消息會在5秒后被刪除,然后又設置了死信的exchange與routingkey。
using (var channel = RabbitMqHelper.GetConnection().CreateModel()) { //聲明一個帶有死信功能功能的queue exchange: dlexchange queue: dlexqueue channel.QueueDeclare("testqueue", true, false, false, new Dictionary<string, object> { { "x-message-ttl",5000}, { "x-dead-letter-exchange", "dlexchange" }, { "x-dead-letter-routing-key", "dlexqueue"} }); //負責死信的交換機 channel.ExchangeDeclare("dlexchange", ExchangeType.Direct, true, false, null); channel.QueueDeclare("dlexqueue", true, false, false, null); channel.QueueBind("dlexqueue", "dlexchange", "dlexqueue", null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (sender, e) => { Console.WriteLine(Encoding.UTF8.GetString(e.Body)); }; channel.BasicConsume("testqueue", true, consumer); Console.WriteLine("consumer啟動成功"); Console.ReadKey(); }
下面則是server端,很簡單,只是發一條消息
//創建返回一個新的頻道 using (var channel = RabbitMqHelper.GetConnection().CreateModel()) { channel.BasicPublish(string.Empty, "testqueue", null, Encoding.UTF8.GetBytes("我五秒后就會消失")); Console.ReadKey(); }
這時候dlexqueue里已經拿到了testqueue里消失的queue,如果這條消息被消費者消費過了的話就不會來到這里了

Maximum priority
不知不覺到了最后一個,這里先說一個場景,當我們打開社交軟件的時候,假如這里同時有十個未讀消息,但是其中有一條消息是你的女票發來的,肯定優先會看女票發來的消息,剩下的才根據其重要程度決定查看的順序。
而Maximnum priority也是為我們的queue內的消息進行分級,根據級別來決定其重要程度。
閑話不多說,直接走代碼,這里是發布者端代碼,設置了五個級別,5最高, 0最低
//創建返回一個新的頻道 using (var channel = RabbitMqHelper.GetConnection().CreateModel()) { channel.QueueDeclare("priorityQueue", true, false, false, new Dictionary<string, object> { { "x-max-priority", 5 } }); var properties = channel.CreateBasicProperties(); for (var i = 0; i < 6; i++) { properties.Priority = (byte)i; channel.BasicPublish(string.Empty, "priorityQueue", properties, Encoding.UTF8.GetBytes($"{i}級別的消息")); } Console.ReadKey(); }
這里不用consumer拿到消息了,直接在WEB UI工具中拿數據,然后看看順序,可以直觀的發現最后發布的一條消息是第一個拿出來的,這就是因為我們設置了級別,而它的優先級是最高的