Rabbitmq的性能测试

在做系统的整体性能测试时发现经常会卡在一个较低的QPS(单机低于100)数值,而且应用服务器的负载不高,检查MQ消费速率只有40左右。接着把目标放在消息发送端上,发现消息发送速率很低,大约40条/s。

果断搭建一个最小化工程单测Rabbitmq发送性能,发现在启用发送端事务后性能下降非常明显。

消息数量开启事务未开启事务
10w320796ms10246ms

本机SSD硬盘测试结果10w条消息未开启事务,大约10s发送完毕;而开启了事务后,需要将近320s,差了30多倍。

接着翻阅Rabbitmq官网,发现开启事务性能最大损失超过250倍。

Using standard AMQP 0-9-1, the only way to guarantee that a message isn't lost is by using transactions -- make the channel transactional then for each message or set of messages publish, commit. In this case, transactions are unnecessarily heavyweight and decrease throughput by a factor of 250. To remedy this, a confirmation mechanism was introduced. It mimics the consumer acknowledgements mechanism already present in the protocol.

事务为什么会慢

rabbitTemplate.setChannelTransacted(true);

该标志位开启后表示Rabbitmq的发送统一被spring事务管理。当一段代码被@Transactional包裹,那么只有当事务结束后,消息才会正在的发送到Rabbitmq的exchange中。具体代码详见rabbitTemplate.java中的doSend()

事务机制是Rabbitmq自身支持的,原理是channel.txSelect()开启事务,channel.txRollback()回滚事务。channel.txCommit()提交事务。当事务开启后,通过抓包会发现网络交互增多。

图片描述

是否可以去掉事务呢?

实践证明,不行

因为某些消息,特别是实体的新增或者更新消息发出后,消费者有可能会通过API反查,这时如果生产者本地事务未提交。消费者就有可能消费到空数据或者旧数据。所以生产者必须将发送消息的事务包裹在本地数据库事务当中。

在过去的实践中,有一种解法可以在不开启事务的情况下解决这个问题,就是利用本地消息表,即生产者调用后不发送,而是将消息写入到本地消息表,当事务失败那么此次写入操作也会回滚。真正发送消息到MQ就开启另一个定时线程轮询该本地消息表异步发送消息。这种方法理论上可行,但实际操作非常复杂,当有多个生产者实例时,定时发送线程也会有多个,那么就会遇到各种并发问题。

最大限度改善性能

既然无法去除事务,并且也不希望代码异常复杂。那么可以将消息分为两类,一类是changlog即实体的变化,一类是command,即通知消费者可以开始做某事,通常用在同步转异步的场景。对于第一类消息仍然保留事务,对于第二类消息关闭发送事务,采用PublisherConfirm的方式保证消息发送成功。

再次测试,性能明显提高,但是并未达到预期,通过innotop命令查看MySQL压力,发现只有10K/s上下。检查Rabbitmq所在机器的负载。

图片描述

iowait非常高,由于该机器上还装有es,同样是io密集型的应用,所以实际性能瓶颈都在磁盘io上了。

跟Devops确认了机器情况,这台机器恰好是Rabbitmq的磁盘节点。为了快速验证,新增了一块SSD硬盘并将Rabbitmq消息文件都挂载到新加的磁盘上。再次测试,iowait下降明显。

图片描述

通过innotop命令查看MySQL压力,发现上升了一倍,达到20K/s。基本上把压力都转到了数据库一侧。系统整体性能提升了一个数量级。也许该Rabbitmq节点独占一台机器效果会更好。

总结

性能优化有时候就像破案,看了jstat没问题,gc没问题,机器负载也不高,就是抓不到“元凶”。需要一点一点的扣,往往一个短板就造成了木桶效应。另外还有一点就是如果硬件能够解决的事情,就不要过度优化软件了,代码复杂度上升往往意味着更多的BUG,在资源有限的情况下多花点钱省点时间还是值得的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ是一个开源的企业级消息队列系统,它具有高度可扩展性和可靠性。在进行RabbitMQ性能压测时,我们可以采取以下几个方面的方法来评估其性能: 1. 高并发测试:通过发送大量的消息并进行高并发的消费操作来测试RabbitMQ的并发性能。可以模拟多个客户端同时发送消息,然后观察RabbitMQ在高并发情况下的处理能力和消息吞吐量。 2. 延迟测试:通过发送一条消息并进行消费的时间来评估RabbitMQ的消息延迟性能。可以通过记录消息发送的时间和消费的时间间隔来计算延迟时间,并观察消息延迟在不同负载下的表现。 3. 持久化消息测试:测试RabbitMQ在持久化消息的情况下的性能表现。可以将消息设置为持久化,然后发送大量的消息并进行消费操作,观察消息的持久化能力和系统的稳定性。 4. 高可靠性测试:测试RabbitMQ在节点故障或网络断开的情况下的可靠性表现。可以模拟节点宕机或网络中断的情况,观察RabbitMQ在故障恢复后是否能够正确处理消息并保持系统的可用性。 在进行性能压测时,需要注意以下几个方面: 1. 测试环境的准备:需要构建一个具有一定规模的测试环境,包括多个生产者、消费者和消息队列节点,以模拟真实的生产环境。 2. 压测工具的选择:可以使用一些专业的压测工具,如Apache JMeter等,来模拟高并发的消息发送和消费操作。 3. 参数的调优:可以尝试调整RabbitMQ的参数,如连接池大小、线程池大小等,以获得更好的性能表现。 4. 结果的分析:在进行性能压测后,需要对测试结果进行分析和比较,以评估系统的性能和稳定性,并找出可能存在的性能瓶颈和优化点。 通过以上的测试和分析,可以对RabbitMQ性能进行全面的评估,并根据实际需求来合理调整配置和优化系统,以提升其性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值