最近在做数据对接的工作,用到了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,消费端无论开几个线程,我们会发现真正处理消息的线程永远只有一个,其它的线程其实都在做无用功,帮不上忙。

spring+activemq中多个consumer同时处理消息时遇到的性能问题的更多相关文章

  1. Spring MVC 中的 forward 和 redirect

    Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染.假设逻辑视图名为 hello,通过配置,我们配置某个 ViewRes ...

  2. SpringMvc(4-1)Spring MVC 中的 forward 和 redirect

    Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染.通过配置,我们配置某个 ViewResolver 如下: <b ...

  3. SpringMvc(4-1)Spring MVC 中的 forward 和 redirect(转)

    Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染.通过配置,我们配置某个 ViewResolver 如下: <b ...

  4. ActiveMQ 中 consumer 的优先级,message 的优先级

    http://activemq.apache.org/consumer-priority.htmlconsumer 优先级 http://activemq.apache.org/activemq-me ...

  5. Spring Boot 监听 Activemq 中的特定 topic ,并将数据通过 RabbitMq 发布出去

    1.Spring Boot 和 ActiveMQ .RabbitMQ 简介 最近因为公司的项目需要用到 Spring Boot , 所以自学了一下, 发现它与 Spring 相比,最大的优点就是减少了 ...

  6. Java ActiveMQ 讲解(二)Spring ActiveMQ整合+注解消息监听

    对于ActiveMQ消息的发送,原声的api操作繁琐,而且如果不进行二次封装,打开关闭会话以及各种创建操作也是够够的了.那么,Spring提供了一个很方便的去收发消息的框架,spring jms.整合 ...

  7. ActiveMQ中Broker的应用与启动方式

    Broker:英语有代理的意思,在activemq中,Broker就相当于一个Activemq实例. 1. 命令行启动实例: 1.activemq start使用默认的activemq.xml启动 E ...

  8. 从Spring容器中获取Bean。ApplicationContextAware

    引言:我们从几个方面有逻辑的讲述如何从Spring容器中获取Bean.(新手勿喷) 1.我们的目的是什么? 2.方法是什么(可变的细节)? 3.方法的原理是什么(不变的本质)? 1.我们的目的是什么? ...

  9. Dubbo在Spring和Spring Boot中的使用

    一.在Spring中使用Dubbo 1.Maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifa ...

随机推荐

  1. iOS中关于UIApplication的详细介绍

    UIApplication 什么是UIApplication? UIApplication对象是应用程序的象征.每一个应用都有自己的UIApplication对象,这个对象是系统自动帮我们创建的, 它 ...

  2. 写论文如何做相关工作(realted work)的调研

    1.找一篇目标研究领域的中文综述,读懂,对该领域有了些基本的了解,如何找到好的综述,就是要关注一些大牛的实验组的综述和进展: 2.找该中文综述引用的外文文献来看,通常是一些比较经典的文献 3.找这些外 ...

  3. LeetCode之“树”:Balanced Binary Tree

    题目链接 题目要求: Given a binary tree, determine if it is height-balanced. For this problem, a height-balan ...

  4. LeetCode之“链表”:Sort List

    题目链接 题目要求: Sort a linked list in O(n log n) time using constant space complexity. 满足O(n log n)时间复杂度的 ...

  5. leetcode之旅(7)-Move Zeroes

    Move Zeroes 题目描述: Given an array nums, write a function to move all 0's to the end of it while maint ...

  6. Sencha touch API

    Sencha touch  API http://docs.sencha.com/touch/2.3.1/#!/guide/getting_started

  7. 简单开发Apple Watch的步骤

    好久没写博客了,自己这两年自从孩子出世,也慢慢懈怠了.实在有点对不住了,换了个新公司,也有点时间可以写写东西了.  前几天苹果刚刚发布Apple Watch,Xcode6也更新了watchKit,正好 ...

  8. mac os x下Dreamweaver如何还原初始配置

    上次在mac下修改Dreamweaver(以下简称dw)时,不知动了哪里,导致打开html文档时设计按钮变灰不能使用!这个太蛋疼了,只能在浏览器中查看效果,live按钮更不用说也是灰化状态. 于是使用 ...

  9. C# 如何在PDF文档中创建表格

    表格能够直观的传达数据信息,使信息显得条理化,便于阅读同时也利于管理.那在PDF类型的文档中如何来添加表格并且对表格进行格式化操作呢?使用常规方法直接在PDF中添加表格行不通,那我们可以在借助第三方组 ...

  10. oracle 修改 字段名称

    暂时应该没有对应的方法,所以我用自己想好的方法去修改 /*修改原字段名name为name_tmp,是将想改名称的字段改为没用/临时的字段*/ Alter  table 表名 rename column ...