2019独角兽企业重金招聘Python工程师标准>>>
##背景 应用中的日志(包括用户操作和服务调用日志)使用rabbitmq缓冲处理,避免应用处理速度慢导致日志堆积内存溢出应用挂掉,最终致使日志丢失。
所以肯定是有用到rabbitmq的confirm、ack、持久化的机制。 现在用户量上来后rmq的cpu就飙得很高。那怎么调优rmq让它cpu不那么高?
##理想步骤 1)使用jemter和vmstat给应用进行负载测试,重现问题场景并粗略观察一下cpu、内存、磁盘io、网络的情况,初步定位调优的方向;
2)通过rmq提供的各种可调的配置。先理解清楚工作原理,知道有哪些处理环节,环节上有哪些配置参数,在具体的问题场景中那些环节的处理是可以少做或不做。需要查看rmq配置文档说明;
3)升级到最新版本,可能最近版本内部有做优化或配置参数有做优化。需要查看release-note;
4)网上找大神的文章;
5)更底层:调优java程序,使用jconsole等各种工具监控观察分析程序的内存,线程,cpu,锁等。所以类似找一下erlang的监控工具监控一下rabbitmq看是否有新发现;
6)根据业务需求进行优化,或使用方式有误,从应用代码里找问题。
##现实 理想很美好,但是实践起来有些力不从心:
1)负载测试结果:发现是cpu和磁盘io很高,内存正常。rmq要做持久化所以io高,也是可以理解的。
2)看完文档后,只找出3个配置项:
-
环境变量的配置文件里的
SERVER_ADDITIONAL_ERL_ARGS="+A 128"
; -
配置信息的配置文件里的hipe_compile;
-
配置信息的配置文件里的
[ {kernel, [ {inet_default_connect_options, [{nodelay, true}]}, {inet_default_listen_options, [{nodelay, true}]} ]} ].
- 升级版本:3.1.5 -> 3.6.4,rmq很久没升级。 release-note说有做persistent优化。因为没有用到新特性,客户端的代码可以和最新版rmq兼容。
4)上网找大神写的文章:找到RabbitMQ初步优化分析报告
- erlang监控工具使用,第4步骤大神就是用这个方法定位问题。之后照着步骤监控做,最后奈何力不从心看不出什么问题不知道大神的调优配置是从哪里设置进去的,没有坚持深究下去。 os_mon, etop 。
6)从业务和应用代码下手,对那些不需要高可靠性的日志不使用confirm、ack、持久化机制。
- confirm关闭: mandatory设置成false
channel. basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
- ack关闭:autoAck设置成true
channel.basicConsume(queueName, autoAck, consumer)
- 持久化: 发送消息时,BasicProperties里的增加一个非持久化标志
##结果
简单盯看top里的%cpu变化:300-400/s的message rates
〉0零处理:70%-100%
〉1简单配置:60%-95%
〉2业务代码改进:30%-50%
〉3升级mq:30%-60%
〉1+2简单配置+业务代码改进:25%-45%
〉1+3简单配置+升级mq:30%-60%
〉2+3业务改进+升级mq:10%-25%
〉1+2+3简单配置+业务代码改进+升级mq:10%-25%
一路下来,没做什么调优,只是把rabbitmq升级了,客户端代码稍微改了一下。rabbitmq把性能耗在了高可靠性。