简体   繁体   English

jms生产商与春天的表现

[英]jms producer performance with spring

i created a simple producer consumer simulation based on spring, jms and activemq, i'm trying to reach high performance from both sides, producers and consumers, 我创建了一个基于spring,jms和activemq的简单的生产者消费者模拟,我试图从双方,生产者和消费者那里获得高性能,

Connection settings : 连接设置:

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
     <property name="connectionFactory"  ref="connectionFactory" />
</bean>

<amq:connectionFactory id="amqConnectionFactory" brokerURL="failover:(tcp://${broker.url}:61616)"  />

<bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="amqConnectionFactory" />
</bean>

<amq:queue id="queue" physicalName="queue" />

<beans:bean id="jsonMessageConverter" class="XXXXX.converter.JsonMessageConverter" />

Consumer settings : 消费者设置:

<jms:listener-container concurrency="10"
    acknowledge="auto" prefetch="1" message-converter="jsonMessageConverter" transaction-manager="transactionManager"

    >
    <jms:listener id="queueListener_1" destination="ooIntegrationQueue"
        ref="myMessageListenerAdapter" />
</jms:listener-container>


<beans:bean id="myMessageListenerAdapter"
    class="org.springframework.jms.listener.adapter.MessageListenerAdapter" >
    <beans:property name="delegate" ref="consumer"/>
</beans:bean>


<beans:bean id="consumer" class="XXX.ConsumerImpl"/>

Producer settings : 制片人设置:

<beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
    p:connectionFactory-ref="connectionFactory" p:messageConverter-ref="jsonMessageConverter"
    p:defaultDestination-ref="ooIntegrationQueue" p:sessionTransacted="true" />

starting with the consumer, i managed to consume about 25 messages per second, which is extremely slow, i discovered the bottleneck to be the fact that i am using transactions, after googling for a bit, and playing with the configs, i found out that after autowiring the DefaultMessageListenerContainer and changing the cachelevel to 从消费者开始,我设法每秒消耗大约25条消息,这是非常慢的,我发现瓶颈是我正在使用交易,谷歌搜索一下,然后玩配置,我发现自动装配DefaultMessageListenerContainer并将cachelevel更改为

listenerContainer.setCacheLevelName("CACHE_SESSION") 

my performance increases to about 1500 messages per second while still having transactions. 我的性能增加到每秒约1500条消息,同时仍然有交易。

my problem is now with the producer which is still stuck at about 25 operations per sec, my producer test is simple : 我的问题是现在生产者仍然停留在每秒约25次操作,我的生产者测试很简单:

int numOfMessages = getNumberOfMessages();


double startTime = System.currentTimeMillis();

for (int i = 1; i <= numOfMessages; i++) {
    jmsTemplate.convertAndSend("HelloWorld" + i);
}

double endTime = System.currentTimeMillis();

double totalTime=(endTime-startTime)/1000;
System.out.println("Time - "+totalTime+" seconds");
System.out.println("EPS - "+numOfMessages/totalTime);

i'm wondering how to reach similiar performances with the producer, since it now bottlenecks the entire system. 我想知道如何与制作人达成类似的表演,因为它现在已经成为整个系统的瓶颈。

Sorry if this answer comes to late to help the original poster. 对不起,如果这个答案来得太晚,以帮助原始海报。 I recently investigated JmsTemplate performance. 我最近调查了JmsTemplate性能。 Even with the same delivery and acknowledgment modes, native JMS code seemed much faster than JmsTemplate . 即使使用相同的传递和确认模式,本机JMS代码似乎比JmsTemplate快得多。 The problem turned out to be that ActiveMQ normally defaults to async sending, but when you use JmsTemplate it instead uses sync sending. 问题是, ActiveMQ通常默认为异步发送,但是当您使用JmsTemplate它会使用同步发送。 This dramatically reduces performance. 这大大降低了性能。 You can set ActiveMQConnectionFactory 's useAsyncSend property to true to force async sending. 您可以将ActiveMQConnectionFactoryuseAsyncSend属性设置为true以强制执行异步发送。 More details here: JmsTemplate is not evil 更多细节: JmsTemplate不是邪恶的

JMSTemplate does a walk of ConnectionFactiory -> Connection -> Session -> MessageProducer, closing each object after each send. JMSTemplate使用ConnectionFactiory - > Connection - > Session - > MessageProducer,每次发送后关闭每个对象。 To get around this, wrap your amqConnectionFactory bean with a org.apache.activemq.pool.PooledConnectionFactory, and use that under the template rather than a CachingConnectionFactory. 要解决此问题,请使用org.apache.activemq.pool.PooledConnectionFactory包装amqConnectionFactory bean,并在模板下使用它而不是CachingConnectionFactory。

Try to change acknowledge method to from AUTO to CLIENT_ACKNOWLEDGE. 尝试将确认方法更改为从AUTO更改为CLIENT_ACKNOWLEDGE。 For more information look to the Specification . 有关更多信息,请参阅规范

What is the default delivery mode for ActiveMQ? ActiveMQ的默认传送模式是什么? is it a persistent queue? 它是一个持久队列吗? if so, how is it configured? 如果是这样,它是如何配置的? how remote is the broker? 经纪人有多远? These answers will determine the basic cost of sending to queue by answering how long it takes the server to ack the send (ie network RTT + potential cost of persisting the message to disk synchronously). 这些答案将通过回答服务器响应发送所需的时间来确定发送到队列的基本成本(即网络RTT +同步将消息持久保存到磁盘的潜在成本)。

The other possibility is that you're actually creating a new connection, session and messageproducer on every send. 另一种可能性是,您实际上是在每次发送时创建新的连接,会话和消息生成器。 This is pretty costly to say the least. 至少可以说这是非常昂贵的。 It will be worth confirming whether this is happening (eg add debug logging to spring, check amq admin console for connection churn) or not as a basic sanity check. 值得确认是否发生这种情况(例如,将调试日志记录添加到spring,检查amq管理控制台是否存在连接流失)或不作为基本的健全性检查。 By the looks of it CachingConnectionFactory should cache a single session and messageproducer by default and convertAndSend should close the session it obtains after sending which results in a returning that cached session to the pool. 通过它的外观CachingConnectionFactory应该默认缓存单个会话和MessageProducer和convertAndSend应该送这会导致缓存的会话返回到池后关闭它获得了会议。 This should mean it is relatively quick (spring jms goes through an awful lot of code just to send a message) to get the cached session on the next send. 这应该意味着它相对较快(Spring jms经历了大量的代码只是为了发送消息)以在下一次发送时获得缓存的会话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM