http://www.cnblogs.com/baibaluo/archive/2012/12/24/2748468.html#2590289

公司有一个应用,多个线程从activeMQ中取消息,随着业务的扩大,该机器占用的网络带宽越来越高。

仔细分析发现,mq入队时并没有异常高的网络流量,仅仅在出队时会产生很高的网络流量。

最终发现是spring的jmsTemplate与activemq的prefetch机制配合导致的问题。

研究源码发现jmsTemplate实现机制是:每次调用receive()时都会创建一个新的consumer对象,用完即销毁。

正常情况下仅仅会浪费重复创建consumer的资源代价,并不至于产生正常情况十倍百倍的网络流量。

但是activeMQ有一个提高性能的机制prefetch,此时就会有严重的问题。

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,并单线程反复使用它来receive(),此时可以充分利用prefetch机制。配合多线程的方式每个线程拥有自己的一个consumer,此时能够充分发挥MQ在大吞吐量时的速度优势。

切记避免多线程使用一个consumer造成的消息混乱。大吞吐量的应用推荐使用方案2,能够充分利用prefetch机制提高系MQ的吞吐性能。

参考文档:

介绍了acrivemq的prefetch机制,每次消费者读取消息时,mq会预先塞给消费者prefetchSize个消息
而jmsTemplate取消息的实现方式为:创建consumer -> 取一个消息 -> 销毁consumer,并没有为consumer做池。
缺省设置时, prefetchSize为1000,prefetch机制取得的后999个消息都白取了。所以必须设置prefetch值为1。
 
activemq的spring支持,文章后半段Working with Spring's JmsTemplate 部分介绍了jmsTemplate
jms连接池只对connection、session、producer组池,而不对consumer做池。
因为prefetch机制的存在,如果对consumer做池,会造成池内的consumer预读取的消息很可能无法被及时处理。

activeMQ消费消息时网络流量异常大的问题的更多相关文章

  1. alluxio网络流量异常分析【转】

    1. 介绍 2. 准备工作 2.1 tcpdump 2.2 winshark 2.3 安装iftop 2.4 alluxio网络通信相关的端口 3.iftop 锁定消耗流量最大的端口 4. dump数 ...

  2. 5-Spark高级数据分析-第五章 基于K均值聚类的网络流量异常检测

    据我们所知,有‘已知的已知’,有些事,我们知道我们知道:我们也知道,有 ‘已知的未知’,也就是说,有些事,我们现在知道我们不知道.但是,同样存在‘不知的不知’——有些事,我们不知道我们不知道. 上一章 ...

  3. 使用isolation forest进行dns网络流量异常检测

    代码如下,测试发现,是否对输入数据进行归一化/标准化对于结果没有影响: import numpy as np from sklearn.ensemble import IsolationForest ...

  4. spring+activemq中多个consumer同时处理消息时遇到的性能问题

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

  5. activemq的消息确认机制ACK

    一.简介 消息消费者有没有接收到消息,需要有一种机制让消息提供者知道,这个机制就是消息确认机制. ACK(Acknowledgement)即确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符 ...

  6. kafka--- consumer 消费消息

    1. consumer API kafka 提供了两套 consumer API: 1. The high-level Consumer API 2. The SimpleConsumer API 其 ...

  7. 网络流量分析——NPMD关注IT运维、识别宕机和运行不佳进行性能优化。智能化分析是关键-主动发现业务运行异常。科来做APT相关的安全分析

    科来 做流量分析,同时也做了一些安全分析(偏APT)——参考其官网:http://www.colasoft.com.cn/cases-and-application/network-security- ...

  8. 【机翻】RTnet – 灵活的硬实时网络框架

    目录 RTnet – 灵活的硬实时网络框架 0 摘要 1 介绍 2 基础服务 2.1 数据包管理 2.2 UDP/IP 实现 2.3 Driver Layer 2.4 应用程序接口 2.5 捕获扩展 ...

  9. 一个链接引发的血案---------服务器 IO及网络流量暴涨解决历程

    在这里介绍一次因为更改网站地址而引发服务器IO读取速度,网络流入流出速度暴涨10倍的解决经历. 环境:Ubuntu + Nginx + php-cgi + Wordpress 事情是这样的,现在网站使 ...

随机推荐

  1. TP5视频教程课程内容

    <TP5 视频教程课程内容> 一.ThinkPHP5TP5 官网基础教程, 官网手册作为参考,讲解TP5的使用方法.理解TP的用途 二.TP5大型项目实战及底层源码分析用TP5 做大型电商 ...

  2. BZOJ2303 APIO2011方格染色

    这题太神了 首先我们可以发现只有当i和j都是偶数时a[1][1]^a[1][j]^a[i][1]^a[i][j]=1才满足情况,其它时都为0 所以我们可以先把i和j都为偶数的地方^1变为0 下面才是最 ...

  3. <摘录>linux文件IO

    这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的 ...

  4. Java常量字符串String理解 String理解

    以前关于String的理解仅限于三点:1.String 是final类,不可继承2.String 类比较字符串相等时时不能用“ == ”,只能用  "equals" 3.Strin ...

  5. 分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?

    作者:何明璐链接:http://www.zhihu.com/question/29483490/answer/98237582来源:知乎著作权归作者所有,转载请联系作者获得授权. 首先是不建议采用XA ...

  6. SQL Server 的事务和锁 图解

    http://www.cnblogs.com/lxconan/archive/2011/10/20/2218396.html

  7. chm TO html 另类方法

    因为网上下了很多chmtohtml ,都是试用版的, 转成html网页格式,总是有限制,或是不完整,我现在找到了一种折中方法,供大家参考 一,我的资源里有工具word to chm  里面有转成网页的 ...

  8. U-Boot中的filesize环境变量

    U-Boot中的环境命令可以使用$(filesize)来确定刚下载(传输)得到的文件大小. 因为使用类似tftp命令传输文件后,会自动更新filesize环境变量.如:setenv updateroo ...

  9. Redis 3.0版本启动时出现警告的解决办法

    原文:http://m.blog.csdn.net/article/details?id=50864933 Redis 3.0.7版本启动时出现警告的解决办法 发表于2016/3/12 12:52:4 ...

  10. 《C++反汇编与逆向分析技术揭秘》之十——析构函数

    局部对象 当对象所在作用域结束之后,销毁栈空间,此时析构函数被调用. 举例: 函数返回时自动调用析构函数: 堆对象 调用析构代理函数来处理析构函数: 为什么使用析构代理函数来调用析构函数?考虑到如果d ...