博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring+activemq中多个consumer同时处理消息时遇到的性能问题
阅读量:6624 次
发布时间:2019-06-25

本文共 1087 字,大约阅读时间需要 3 分钟。

最近在做数据对接的工作,用到了activemq,我需要从activemq中接收消息并处理,但是我处理数据的步骤稍微复杂,渐渐的消息队列中堆的数据越来越多,就想到了我这边多开几个线程来处理消息。

可是会发现,服务器占用的网络带宽变的异常的高,仔细分析发现,mq入队时并没有异常高的网络流量,仅仅在出队时会产生很高的网络流量。最终发现是spring的jmsTemplate与activemq的prefetch机制配合导致的问题。研究源码发现jmsTemplate实现机制是:每次调用receive()时都会创建一个新的consumer对象,用完即销毁。正常情况下仅仅会浪费重复创建consumer的资源代价,并不至于产生正常情况十倍百倍的网络流量。但是activeMQ有一个提高性能的机制prefetch,此时就会有严重的问题。

ActiveMq的prefetch机制:

每次consumer连接至MQ时,MQ预先存放许多message到消费者(前提是MQ中存在大量消息),预先存放message的数量取决于prefetchSize(默认为1000)。此机制的目的很显然,是想让客户端代码用一个consumer反复进行receive操作,这样能够大量提高出队性能。

此机制与jmsTemplate配合时就会产生严重的问题,每次jmsTemplate.receive(),都会产生1000个消息的网络流量,但是因为jmsTemplae并不会重用consumer,导致后面999个消息都被废弃。反复jmsTemplate.receive()时,表面上看不出任何问题,其实网络带宽会造成大量的浪费

解决方案

1、若坚持使用jmsTemplate,需要设置prefetch值为1,相当于禁用了activeMQ的prefetch机制,此时感觉最健壮,就算多线程,反复调用jmsTemplate.receive()也不会有任何问题。但是会有资源浪费,因为要反复创建consumer并频繁与服务器进行数据通信,但在性能要求不高的应用中也不算什么问题。

2、不使用jmsTemplate,手工创建一个consumer,此时可以充分利用prefetch机制。配合多线程的方式每个线程拥有自己的一个consumer,此时能够充分发挥MQ在大吞吐量时的速度优势。

 

ps:如何看到activeMQ的prefetch机制?

prefetchsize值默认是1000,那么只要队列里的消息小于1000,消费端无论开几个线程,我们会发现真正处理消息的线程永远只有一个,其它的线程其实都在做无用功,帮不上忙。

转载地址:http://eztpo.baihongyu.com/

你可能感兴趣的文章
Multipart Internet Mail Extensions (MIME)
查看>>
C# WinForm控件之Dock顺序调整
查看>>
中控科技 ZK Software的售后服务真像一坨屎,技术人员嚣张
查看>>
NSPredicate过滤数组数据
查看>>
设置MYSQL允许用IP访问
查看>>
spark 数据预处理 特征标准化 归一化模块
查看>>
大道至简,系统设计和模块划分的实用经验之谈
查看>>
正则表达式中参数g、i、m的作用(share)
查看>>
使用Solr构建企业级的全文检索(四)---------写入文档
查看>>
Routing Error uninitialized constant TransController
查看>>
设计模式(二): BUILDER生成器模式 -- 创建型模式
查看>>
git: No refs in common and none specified; doing no
查看>>
I.MX6 天嵌 E9 U-boot menu hacking
查看>>
Eclipse中Android项目引用其他项目时链接源码的方法
查看>>
Mac PD虚拟机卸载删除
查看>>
java中String、StringBuffer、StringBuilder的区别
查看>>
EL 表达式
查看>>
WPF水珠效果按钮组
查看>>
一个不错的命令行解析类
查看>>
I.MX6 FFmpeg 录制视频
查看>>