热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[1149]RabbitMQCPU占用过高优化

文章目录背景问题排查error_logger问题erlang调度器问题总结背景服务器上搭建的RabbitMQ在并发量不是很大的情况下CPU占用竟然达到了40%左右,

文章目录

      • 背景
      • 问题排查
      • error_logger 问题
      • erlang 调度器问题
      • 总结


背景

服务器上搭建的 RabbitMQ 在并发量不是很大的情况下 CPU 占用竟然达到了 40% 左右,这种情况第一感觉是不科学的,推测应该是使用不当或哪里配置不合理造成的。

问题排查

首先通过 top 命令查看到 CPU 和 内存使用情况:
image.png

error_logger 问题

然后可以通过 RabbitMQ 提供的插件 rabbitmq_top 来查看详细的各个线程内存和 CPU 的使用情况。首先我们通过命令 rabbitmq-plugins list 查看所有插件及开启情况,然后使用命令 rabbitmq-plugins enable rabbitmq_top 开启插件,关闭插件的命令是 rabbitmq-plugins disable rabbitmq_top 。这样开启后就能在 RabbitMQ 的管理后台查看了。如下图:

然后点击 Reductions / sec 排序,这个值越大表示的 CPU 的使用越高。会发现 error_logger 程序的 CPU 使用最高,从描述上看是和日志相关。
image.png

自然地要去看日志输出有没有什么异常,通过查看日志文件发现并没有什么异常,而且日志输出的内容很少。然后改变了日志等级为 debug (rabbitmqctl set_log_level debug)看下详细的日志,发现有start_link 日志。

2020-05-21 10:43:01.177 [debug] <0.21161.3240> Supervisor {<0.21161.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.176195>, 1571, 131072, rabbit_framing_amqp_0_9_1, <0.29275.7908>, {<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}, true) at pid <0.20273.3240>
2020-05-21 10:43:01.177 [debug] <0.21161.3240> Supervisor {<0.21161.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}) at pid <0.21143.3240>
2020-05-21 10:43:01.177 [debug] <0.21161.3240> Supervisor {<0.21161.3240>,rabbit_channel_sup} started rabbit_channel:start_link(1571, <0.29275.7908>, <0.20273.3240>, <0.29275.7908>, <<"10.244.5.77:58214 -> 10.244.3.9:5672">>, rabbit_framing_amqp_0_9_1, {user,<<"guest">>,[administrator],[{rabbit_auth_backend_internal,none}]}, <<"...">>, [{<<"exchange_exchange_bindings">>,bool,true},{<<"connection.blocked">>,bool,true},{<<"authentica...">>,...},...], <0.29654.7908>, <0.21143.3240>) at pid <0.20766.3240>
2020-05-21 10:43:01.225 [debug] <0.21123.3240> Supervisor {<0.21123.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.80537>, 41, 131072, rabbit_framing_amqp_0_9_1, <0.28490.3357>, {<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}, true) at pid <0.21071.3240>
2020-05-21 10:43:01.225 [debug] <0.21123.3240> Supervisor {<0.21123.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}) at pid <0.20379.3240>
2020-05-21 10:43:01.225 [debug] <0.21123.3240> Supervisor {<0.21123.3240>,rabbit_channel_sup} started rabbit_channel:start_link(41, <0.28490.3357>, <0.21071.3240>, <0.28490.3357>, <<"10.244.2.171:55900 -> 10.244.3.9:5672">>, rabbit_framing_amqp_0_9_1, {user,<<"guest">>,[administrator],[{rabbit_auth_backend_internal,none}]}, <<"...">>, [{<<"exchange_exchange_bindings">>,bool,true},{<<"connection.blocked">>,bool,true},{<<"authentica...">>,...},...], <0.28524.3357>, <0.20379.3240>) at pid <0.21072.3240>
2020-05-21 10:43:01.229 [debug] <0.21280.3240> Supervisor {<0.21280.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.176195>, 1571, 131072, rabbit_framing_amqp_0_9_1, <0.29275.7908>, {<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}, true) at pid <0.21014.3240>
2020-05-21 10:43:01.229 [debug] <0.21280.3240> Supervisor {<0.21280.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}) at pid <0.20939.3240>
2020-05-21 10:43:01.230 [debug] <0.21280.3240> Supervisor {<0.21280.3240>,rabbit_channel_sup} started rabbit_channel:start_link(1571, <0.29275.7908>, <0.21014.3240>, <0.29275.7908>, <<"10.244.5.77:58214 -> 10.244.3.9:5672">>, rabbit_framing_amqp_0_9_1, {user,<<"guest">>,[administrator],[{rabbit_auth_backend_internal,none}]}, <<"...">>, [{<<"exchange_exchange_bindings">>,bool,true},{<<"connection.blocked">>,bool,true},{<<"authentica...">>,...},...], <0.29654.7908>, <0.20939.3240>) at pid <0.21039.3240>
2020-05-21 10:43:01.253 [debug] <0.20564.3240> Supervisor {<0.20564.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.80537>, 41, 131072, rabbit_framing_amqp_0_9_1, <0.28490.3357>, {<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}, true) at pid <0.20612.3240>
2020-05-21 10:43:01.253 [debug] <0.20564.3240> Supervisor {<0.20564.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}) at pid <0.20962.3240>
2020-05-21 10:43:01.254 [debug] <0.20564.3240> Supervisor {<0.20564.3240>,rabbit_channel_sup} started rabbit_channel:start_link(41, <0.28490.3357>, <0.20612.3240>, <0.28490.3357>, <<"10.244.2.171:55900 -> 10.244.3.9:5672">>, rabbit_framing_amqp_0_9_1, {user,<<"guest">>,[administrator],[{rabbit_auth_backend_internal,none}]}, <<"....">>, [{<<"exchange_exchange_bindings">>,bool,true},{<<"connection.blocked">>,bool,true},{<<"authentica...">>,...},...], <0.28524.3357>, <0.20962.3240>) at pid <0.20158.3240>
2020-05-21 10:43:01.260 [debug] <0.21185.3240> Supervisor {<0.21185.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.176195>, 1571, 131072, rabbit_framing_amqp_0_9_1, <0.29275.7908>, {<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}, true) at pid <0.20278.3240>
2020-05-21 10:43:01.260 [debug] <0.21185.3240> Supervisor {<0.21185.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.5.77:58214 -> 10.244.3.9:5672">>,1571}) at pid <0.20461.3240>
2020-05-21 10:43:01.261 [debug] <0.21185.3240> Supervisor {<0.21185.3240>,rabbit_channel_sup} started rabbit_channel:start_link(1571, <0.29275.7908>, <0.20278.3240>, <0.29275.7908>, <<"10.244.5.77:58214 -> 10.244.3.9:5672">>, rabbit_framing_amqp_0_9_1, {user,<<"guest">>,[administrator],[{rabbit_auth_backend_internal,none}]}, <<"....">>, [{<<"exchange_exchange_bindings">>,bool,true},{<<"connection.blocked">>,bool,true},{<<"authentica...">>,...},...], <0.29654.7908>, <0.20461.3240>) at pid <0.20990.3240>
2020-05-21 10:43:01.268 [debug] <0.21033.3240> Supervisor {<0.21033.3240>,rabbit_channel_sup} started rabbit_writer:start_link(#Port<0.80537>, 41, 131072, rabbit_framing_amqp_0_9_1, <0.28490.3357>, {<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}, true) at pid <0.20840.3240>
2020-05-21 10:43:01.269 [debug] <0.21033.3240> Supervisor {<0.21033.3240>,rabbit_channel_sup} started rabbit_limiter:start_link({<<"10.244.2.171:55900 -> 10.244.3.9:5672">>,41}) at pid <0.21042.3240>

后来经过一系列的查找&#xff0c;在生产者发生完消息后&#xff0c;执行下面语句能够减少日志输出&#xff1a;

RabbitUtils.isPhysicalCloseRequired();

修改完客户端的代码后&#xff0c;发现rabbitMQ 的 CPU 降了几个百分点&#xff0c;但是还是很高。那么就表明 CPU 的占用高不是因为 error_logger 引起的。

erlang 调度器问题

通过 top -H -p PID 命令查看 beam.smp 进程里的每个线程的 CPU 使用情况&#xff1a;
image.png

发现主要是 erlang 语言的两个调度器&#xff08;调度器有关文档&#xff1a;https://hamidreza-s.github.io/erlang/scheduling/real-time/preemptive/migration/2016/02/09/erlang-scheduler-details.html&#xff09;占用 CPU。通过命令 rabbitmq-diagnostics runtime_thread_stats 查看线程的运行状况&#xff0c;发现两个调度器的 sleep 时间在 99 % &#xff0c;也就是说调度器大部分时间是空闲的。在官方文档中有一节讲到了 CPU 相关的内容&#xff1a;https://www.rabbitmq.com/runtime.html#cpu。里面提到了调度器在从 sleep 状态转换成工作状态是需要一定的成本的&#xff0c;因此在调度器没有任务调度时默认会延迟一段时间才进入 sleep 状态&#xff0c;调度器的忙等待是会占用 CPU的。因此我们可以通过禁用忙等待来降低 CPU 的消耗&#xff1a;

RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS&#61;"&#43;sbwt none &#43;sbwtdcpu none &#43;sbwtdio none"

这条配置需要添加到文件 /etc/rabbitmq/rabbitmq-env.conf 中&#xff0c;如果没有则创建该文件。

文档上还给出了&#xff0c;在共享或CPU受限的环境&#xff08;包括容器化的环境&#xff09;中&#xff0c;可能需要显式配置调度程序个数。我们也可以通过改变调度器个数来降低 CPU 的消耗&#xff1a;

RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS&#61;"&#43;S 1:1"

上面的两种方式的修改经过压测都可以有效的降低 CPU 的占用&#xff0c;效果上相差不大&#xff0c;在多核 CPU 的情况下多个调度器可能 CPU 的利用率更高。在实际的应用中要根据实际情况进行选择。

总结

上面主要介绍了 RabbitMQ 占用 CPU 高的排查过程和解决方案&#xff0c;一种方案是禁止调度器忙等&#xff0c;另一种是通过减少调度器的个数。这两种方案的选择还要根据实际情况进行选择&#xff0c;比如消息的生产/消费并发量&#xff0c;或着服务器的配置等。

来源&#xff1a;https://blog.csdn.net/u010657094/article/details/106392113
https://www.codenong.com/cs106392113/
https://stackoom.com/question/1hZuW
https://blog.csdn.net/whatday/article/details/114478698
https://blog.csdn.net/qq_18630487/article/details/113681802


推荐阅读
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • Linuxchmod目录权限命令图文详解在Linux文件系统模型中,每个文件都有一组9个权限位用来控制谁能够读写和执行该文件的内容。对于目录来说,执行位的作用是控制能否进入或者通过 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • 本文讨论了在dva中引入antd组件table时没有显示样式的问题。提供了.roadhogrc文件的配置,包括环境和import的设置。同时介绍了extraBabelPlugins和transform-runtime的使用方法,并解释了libraryName和css的含义。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • 这个问题困扰了我两天,卸载Dr.COM客户端(我们学校上网要装这个客户端登陆服务器,以后只能在网页里输入用户名和密码了),问题解决了。问题的现象:在实验室机台式机上安装openfire和sp ... [详细]
  • RabbitMq之发布确认高级部分1.为什么会需要发布确认高级部分?在生产环境中由于一些不明原因,导致rabbitmq重启,在RabbitMQ重启期间生产者消息投递失败,导致消息丢 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
  • 多线程补充(一)JVM内存结构 VS Java内存模型 VS Java对象模型
    一:Java内存结构参考:https:www.zhihu.comquestion64586462answer576543433内存结构࿱ ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有