首页 » PHP教程 » rabbitmqvhostphp技巧_NET Core中的RabbitMQ消费者CPU高竟然是这个原因

rabbitmqvhostphp技巧_NET Core中的RabbitMQ消费者CPU高竟然是这个原因

duote123 2024-12-10 0

扫一扫用手机浏览

文章目录 [+]

"大众年夜众号:不止dotNET

在 RabbitMQ 中有一个 vhsot 机制,可以用来做租户隔离,当产品从单租户蜕变为多租户时,恰好可以用到这个特性,不同 vhost 中的交流机、行列步队互不影响。

rabbitmqvhostphp技巧_NET Core中的RabbitMQ消费者CPU高竟然是这个原因

起初在产品中引入 RabbitMQ 的时候,版本如下:

rabbitmqvhostphp技巧_NET Core中的RabbitMQ消费者CPU高竟然是这个原因
(图片来自网络侵删)
RabbitMQ:3.7.2 (后来升级为 3.8.2)RabbitMQ Client:5.1.2.NET Core:3.1

通过一段韶光的努力,产品终于支持多租户模式了,测试在做测试的时候创造了一个问题,随着租户数添加的越来越多,RabbitMQ 消费者的 CPU 占用也越来越高。

100 旁边的租户数,每个租户行列步队大概 10 几个,这时 CPU 占用稳定在 50% 旁边,纵然系统没有任何人访问。

剖析下可能的缘故原由:

因产品比较繁芜,可能是其代码影响到;可能是 RabbitMQ 的参数问题;可能是 .NET Core 中的驱动的问题,可以考试测验下 Java 。

正式进入问题的排查。

大略示例

1、在 .NET Core 3.1 中编写一个大略的 RabbitMQ 示例:

public void Start(){ Console.WriteLine("App Start..."); _defMqConfig = new MQConfig() { MQAutomaticRecoveryEnabled = true, MQHeartBeat = 5, MQNetworkRecoveryInterval = 5, MQVHost = "/", MQHostName = _mqHostName, MQUserName = _mqUserName, MQPassword = _mqPassword, MQPort = _mqPort, MQServerPort = string.IsNullOrEmpty(_mqServerPort) ? $"1{_mqPort}" : _mqServerPort }; Console.WriteLine(" MQ vhost init Start..."); string prefix = "testhost"; for (int i = 0; i < 200; i++) { string vhost = $"{prefix}{i}"; InitAllVhost(vhost); Console.WriteLine($" 初始化vhost:{vhost}..."); } Console.WriteLine(" MQ vhost init Done..."); Console.WriteLine("App Start Done...");}private void InitAllVhost(string vhost){ string url = $"http://{_mqHostName}:{_mqServerPort}"; _mqManager.AddVirtualHost(url, vhost, _mqUserName, _mqPassword); _defMqConfig.MQVHost = vhost; _mqManager.Subscribe(_defMqConfig);}

2、监听的代码如下:

public void Subscribe(MQConfig engineConfig){ var factory = new ConnectionFactory(); factory.HostName = engineConfig.MQHostName; factory.UserName = engineConfig.MQUserName; factory.Password = engineConfig.MQPassword; factory.VirtualHost = engineConfig.MQVHost; factory.RequestedHeartbeat = (ushort) engineConfig.MQHeartBeat; factory.AutomaticRecoveryEnabled = true; factory.NetworkRecoveryInterval = new TimeSpan(engineConfig.MQNetworkRecoveryInterval); var connection = factory.CreateConnection(); var channel = connection.CreateModel(); channel.QueueDeclare("TestQueue", false, false, false, null); channel.ExchangeDeclare("TestQueueExchange", ExchangeType.Direct, false, false, null); var consumer = new EventingBasicConsumer(channel); channel.BasicConsume("TestQueue", false, consumer); channel.QueueBind("TestQueue", "TestQueueExchange", "TestQueueExchange"); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine("已吸收: {0}", message); };}

3、上面代码创建了 200 个 vhost ,每个 vhost 中 1 个行列步队,程序运行后不雅观察 cpu 如下图:

4、在 Subscribe 方法中有创建 Connection 和 CreateModel 方法,如果利用 using 或在方法末了对其进行开释,CPU 会是一个正常的状态,但也就吸收不到了。

调度参数

1、在 RabbitMQ 中有两个参数 MQHeartBeat、MQNetworkRecoveryInterval :

MQHeartBeat:心跳检测MQNetworkRecoveryInterval:掉线重连

2、不断调度这两个参数的值,进行考试测验,创造 CPU 并没有明显改进。

考试测验 Java

当没有什么头绪的时候,就会采取各种办法进行考试测验,来打消问题,以是决定用 Java 试试。

在 Java 程序中,利用的 RabbitMQ 客户端为 rabbitmq-java-client ,版本为 5.14.2 ,由于之前在 .NET 程序验证时已经创建了 vhost ,以是在 Java 程序中只写了消费者进行监听。

当 Java 程序跑起来的时候,创造 CPU 占用是正常的,在遍历 vhost 监听的过程中 CPU 有所颠簸,遍历完后 ,CPU 占用比较稳定。

真正的缘故原由

这时基本可以确定,是 .NET Core 的 RabbitMQ 客户真个问题,到这时才想起有可能是 .NET Core RabbitMQ 客户真个版本问题,检讨创造目前利用的版本是 5.1.2,而最新的版本为 6.3.0 。

升级 .NET Core RabbitMQ 到最新版本,升级后有两个地方不兼容:

RequestedHeartbeat 类型变成了 TimeSpan;吸收的由 byte[] 变成了 ReadOnlyMemory类型。

修正这两处后,赶紧运行进行测试,CPU 终于正常了。

查看了下 RabbitMQ 客户端在 GitHub 上的更新记录,创造在版本 6.2.4 中有修复一个关于连接的 Bug:

又连续将版本回退到 6.2.3 进行测试,问题又能重现了,就更加确定了这个问题是在 6.2.4 中办理了。

末了

现在无论是做项目还是做产品,都会利用很多中间件,这些中间件和干系的库也是在不断地更新迭代的,当我们进行功能迭代的同时,也须要关注这些中间件的发展,在新的版本中供应了什么新特性,修复了什么问题,这给我们是否升级供应依据。

希望本文对您有所帮助!

标签:

相关文章

phpmongodb对象技巧_MongoDB 编程

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 措辞编写。旨在为 WEB 运用供应可扩展的高性能数据存储办理方案。M...

PHP教程 2024-12-12 阅读0 评论0