小菜一只,上面安排优化ActiveMQ的配置。。。我到处瞎鼓捣,现在发送者的速度贼快达到 5000条/s, 我看了网上许多资料,说采用两个连接池来区分。。 求大神给个思想怎么优化消费者的速度,下面上配置: <bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="${jms.brokerURL}" /> <property name="userName" value="${jms.username}" /> <property name="password" value="${jms.password}" /> <property name="dispatchAsync" value="true" /> <property name="useAsyncSend" value="true" /> </bean> <!-- 设置发送连接池,提高性能 --> <bean id="JmsSenderFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> <property name="connectionFactory" ref="jmsFactory" /> <property name="maxConnections" value="100"></property> </bean> <!-- 设置接收连接池,提高性能 --> <bean id="JmsReveiverFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory" ref="jmsFactory" /> <property name="maxConnections" value="100"></property> </bean> <!-- Spring JMS Template --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="JmsSenderFactory" /> <property name="defaultDestination" ref="destination" /> <!-- 区别它采用的模式:false是p2p;true是订阅 --> <property name="pubSubDomain" value="false" /> <property name="messageConverter"> <bean class="org.springframework.jms.support.converter.SimpleMessageConverter" /> </property> </bean> <!-- Spring JMS Template --> <bean id="jmsTemplate2" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="JmsReveiverFactory" /> <property name="defaultDestination" ref="destination" /> <!-- 区别它采用的模式:false是p2p;true是订阅 --> <property name="pubSubDomain" value="false" /> <property name="messageConverter"> <bean class="org.springframework.jms.support.converter.SimpleMessageConverter" /> </property> </bean> <!-- 发送消息的目的地(一个队列) --> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <!-- 设置消息队列的名字 --> <constructor-arg index="0" value="${jms.queueName}" /> </bean> <!-- 消息监听 --> <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="${jms.concurrentConsumers}" /> <property name="connectionFactory" ref="JmsReveiverFactory" /> <property name="destinationName" value="${jms.queueName}" /> <property name="messageListener" ref="messageConsumer" /> <property name="sessionTransacted" value="true"/> <property name="pubSubNoLocal" value="true"></property> </bean> <!-- 消息消费者 --> <bean id="messageConsumer" class="com.voole.jms.MessageConsumer"> <property name="jmsTemplate2" ref="jmsTemplate2"></property> </bean> <!-- 消息生产 --> <bean id="messageProducer" class="com.voole.jms.MessageProducer"> <property name="jmsTemplate" ref="jmsTemplate"></property> </bean> </beans> 就不发到中间件了,我估计这儿的人多点。。。没多少分了,求大神解惑~小弟感激不尽。 |
|
大神们,给个思路吧。。。
|
|
有点看不懂你提出的问题啊,难道我水平不够?期待真正的高手。
|
|
就是如何提升消费者的速度~~~ |
|
20分 |
你确定你的消费者那部分代码能高速消费?
|
如何提升消费者的速度,取决于消费者的逻辑,我给你这样的消费者逻辑:
public void run() { 你把框架折腾烂了都无法改善你消息堆积的情况 |
|
不知道,略过、、、
|
|
消费者可是设置并行的消费数,也就是再并行同一时间消费的数量。默认好像是5,具体可以自己调整。
mdb中的maxSession字段 |
|
如果事物长时间占用,减少事物超时的时间,尽快的消费掉。能够让接下去的任务到达。
transactionTimeout |
|
30分 |
先查看一下你消费者的逻辑和性能吧,如果本身的性能很差,在jms这一层上优化余地有限.如果你的消费者什么操作都没有,应该不会那么慢的。
|
如果是项目的要求的话,应该根据业务逻辑确定性能需求。只要满足需求就可以了。否则优化就是一个无底洞了
|
|
10分 |
我也碰到过同样的问题,使用JMS来远程调用出现慢速消费者的问题.
我是这样解决的,消费者我只生成一个,这个消费者统一的来拿取消息. 首先我建立了这样一个类. private static class MessageProbe { private Object returnValue; private CountDownLatch latch = new CountDownLatch(1); public Object await() throws InterruptedException { latch.await(); return returnValue; } public Object await(long timeout) throws InterruptedException, TimeoutException { boolean noTimeout = false; noTimeout = latch.await(timeout, TimeUnit.MILLISECONDS); if (noTimeout) { return returnValue; } else { throw new TimeoutException("Response message timed out."); } } public void obtainRetunValue(Object value) { returnValue = value; latch.countDown(); } } 发出调用请求后我就生成一个”MessageProbe”的实例,然后交给之前生成的消费者. Map<String, MessageProbe> registerPool = new ConcurrentHashMap<String, MessageProbe>(); 一个简单的JDK5提供的Map实现,就能满足消费者持有这些”MessageProbe”实例的要求了. 调用线程只需要阻塞在MessageProbe.awit()方法上即可. |
如果你之前的消费者是处理完业务逻辑后才返回,可以尝试下这种优化方式:
消费者在刚拿到消息后,直接把消息放入另一个队列,然后立刻返回等待下次消费,而那个消息队列通过另一个线程池去不停的获取消息进行业务处理,这样,可以是消费者响应速度大幅提升 |
|
路过太专业了啊
|
|
过
|
|
<property name=”pubSubDomain” value=”true” /> 采用订阅方式 , 监听器发部到多个机器上。 会分解一些压力
|
|
我也遇到这个问题。。。。。。。请问楼主解决了否???
|
|
开线程去处理业务,貌似不是好办法。。。。因为处理业务有频繁的去相同的表插入数据。。。猜测这样很可能导致数据库死锁。。。觉得不太实用。。 |
|
多线程插表如果就会死锁的话,那高并发的项目还能活吗- – |