.netcore3.1 RabbitMq Lazy Queue 电脑版发表于:2021/2/4 16:15 ![](https://img.tnblog.net/arcimg/hb/585b0f1ffa7f4c2095baa20c175b32a0.png) >#.netcore3.1 RabbitMq Lazy Queue [TOC] tn>从`RabbitMQ 3.6.0`开始,代理具有`惰性队列`的概念-队列实际上将其内容尽早移至磁盘,并且仅在消费者要求时才将其内容加载到`RAM(内存)`中,因此是`Lazy`。 没有Lazy的出现了什么问题 ------------ tn>惰性队列的主要目标之一是能够支持很长的队列(数百万条消息)。由于各种原因,队列可能会变得很长: - 消费者离线/崩溃/需要维护 - 突然出现消息入侵高峰,生产者的速度超过了消费者 - 消费者比正常人慢 tn>默认情况下,队列保留消息的内存缓存,该缓存在消息发布到RabbitMQ中时被填充。此缓存的想法是能够尽快将消息传递给使用者。请注意,持久性消息可以在它们进入代理时写入磁盘并同时保留在RAM中。 ![](https://img.tnblog.net/arcimg/hb/5fbc19064f7248c589b4a43fe4d37622.png) 使用Lazy Queue + inMemory的方式 ------------ ![](https://img.tnblog.net/arcimg/hb/52bb2245d7a94fe79f249d2eb59eedaf.png) tn>我们声明一个`Lazy`队列,并在其中添加`Int.MaxValue`条数据看看观察中图的内存变化与磁盘变化。 ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { // 声明一个Single_Active_Consumer_Queue队列 channel.QueueDeclare( queue: "my_lazy_test", durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object>() { { "x-queue-mode","lazy" } }); for (int i = 0; i < int.MaxValue; i++) { var msg = Encoding.UTF8.GetBytes($"Publish Message {i}"); channel.BasicPublish(string.Empty, "my_lazy_test", null, msg); Console.WriteLine($"Publish Message {i}"); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } ``` ![](https://img.tnblog.net/arcimg/hb/4d13aea695ab4169bd6f25e75a99f3f0.png) ![](https://img.tnblog.net/arcimg/hb/dcfa2ed85fa9472097fa1bffff2410bf.png) ![](https://img.tnblog.net/arcimg/hb/7e31d10f01ec459a9520bdd2680e45ba.png) ![](https://img.tnblog.net/arcimg/hb/d0896928f9a841aab12bd382bffefb67.png) ![](https://img.tnblog.net/arcimg/hb/8794f9a3607b4e3aa7b4bd0400e5c3ed.png) ![](https://img.tnblog.net/arcimg/hb/76a11e6b98df431b90650ea5ee0a4ef1.png) tn>我们刚开始内存截图大概是`197`,然后逐渐升高到`246`左右的时候,就升不上去了。网络的读写大概是在`1Mib`左右,但写到磁盘的速度是`6.35M/s`左右。是相当稳当的。最后清理一下消息。 使用Default Queue + inMemory的方式 ------------ tn>这种模式不仅在内存上逐步升高,在内存急缺的情况下容易导致内存溢出的情况。 ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { // 声明一个Single_Active_Consumer_Queue队列 channel.QueueDeclare( queue: "my_default_test", durable: true, exclusive: false, autoDelete: false, arguments: null); for (int i = 0; i < int.MaxValue; i++) { var msg = Encoding.UTF8.GetBytes($"Publish Message {i}"); channel.BasicPublish(string.Empty, "my_default_test", null, msg); Console.WriteLine($"Publish Message {i}"); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } ``` ![](https://img.tnblog.net/arcimg/hb/c4027a19ed514e2d89ac342b45084749.png) ![](https://img.tnblog.net/arcimg/hb/719b9d16f3774be29ff0b5f9f747b2ef.png) ![](https://img.tnblog.net/arcimg/hb/724a65cd060f490baf057e29c079d704.png) ![](https://img.tnblog.net/arcimg/hb/e37cac76c68f463590c5315581839613.png) tn>我们看到`内存`和`CPU`是步步高升,这才`1百万`条就感觉要残废的样子。 其他 ------------ tn>建议大家使用的时候呢,最好是`Lazy Queue`和`Persistent`消息的持久化属性一起使用,效果会更好!