JMS模板性能差224ms发布消息

时间:2014-06-10 22:58:21

标签: spring spring-jms

即使使用了JNDI连接工厂,Spring JMStemplate也需要大约200到240毫秒才能发布消息。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jms="http://www.springframework.org/schema/jms" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/oxm  http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">




    <beans:bean id="jmsConnectionFactory" 
           class="org.springframework.jndi.JndiObjectFactoryBean">
        <beans:property name="jndiName" value="jms/TesService"/>
        <beans:property name="resourceRef" value="false"/>
        <beans:property name="lookupOnStartup" value="false"/>
        <beans:property name="cache" value="true"/>
        <beans:property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
    </beans:bean>

    <jms:listener-container acknowledge="transacted" cache="session" connection-factory="jmsConnectionFactory"
        concurrency="1" container-type="default"
        container-class="org.kp.oppr.ancillary.jms.container.TesMessageListenerContainer">
        <jms:listener id="QL.TEST.84" destination="QL.TEST.OUTPUT.84" ref="ancillaryMessageListener" method="onMessage" />
        <jms:listener id="QL.TEST.85" destination="QL.TEST.OUTPUT.85" ref="ancillaryMessageListener" method="onMessage" />
    </jms:listener-container>


    <beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <beans:property name="sessionTransacted" value="true" />
        <beans:property name="pubSubDomain" value="false" />
        <beans:property name="connectionFactory" ref="jmsConnectionFactory"></beans:property>
    </beans:bean>

    <!-- JMS Beans -->
    <beans:bean id="jmsMessageProducer" class="org.kp.oppr.test.helpers.JmsMessageProducer">
    <beans:property name="jmsTemplate" ref="jmsTemplate"></beans:property>
    </beans:bean>

    <beans:bean id="testMessageListener" class="org.kp.oppr.test.jms.listener.TestMessageListener" scope="prototype">
    <beans:property name="retryDelay" value="${retry.delay}"></beans:property>
    <beans:property name="maxRetry" value="${retry.allowed}"></beans:property>


    </beans:bean>

和发布消息的类是

  package org.test.helpers;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import com.ibm.mq.jms.MQQueue;

public class JmsMessageProducer {

    private static final Logger LOGGER = LoggerFactory.getLogger(JmsMessageProducer.class);
    private JmsTemplate jmsTemplate;
    private MQQueue queue;


    public MQQueue getQueue() {
        return queue;
    }

    public void setQueue(MQQueue queue) {
        this.queue = queue;
    }



    /**
     *
     */
    public void sendMessage(final String message, final String queueName) throws JMSException {

        MQQueue queue = new MQQueue(queueName);
        queue.setTargetClient(1);       


        long queueStartTime = System.currentTimeMillis();

        jmsTemplate.send(queue, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage(message);
                //message.setIntProperty(MESSAGE_COUNT, index);

                return textMessage;
            }
        });

        if(LOGGER.isInfoEnabled()) {
            LOGGER.info("Queue put time: " + (System.currentTimeMillis() - queueStartTime) + " queue: " + queue.getQueueName());
            LOGGER.info("Sent message to queue: " + queue.getQueueName() + " message: " + message);
        }

    }

    public JmsTemplate getJmsTemplate() {
        return jmsTemplate;
    }

    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }
}



</beans:beans>

`

队列放置时间为220ms。 JNDI连接工厂在Web sphere 8.5上...理想情况下它不应超过30ms ..

如果我在配置文件中遗漏了某些内容,请告诉我

1 个答案:

答案 0 :(得分:0)

当前为每个发送操作使用缓存,检索Connection,用于创建Session,用于创建Producer。这是所有开销和延迟(可能大部分时间浪费在创建Session

您可以配置CachingConnectionFactory,或者只需要一个连接时使用SingleConnectionFactory。有关更多信息,请查看the reference guide

<beans:bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <beans:property name="targetConnectionFactory" ref="jmsConnectionFactory" />
</beans:bean>

<beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <beans:property name="sessionTransacted" value="true" />
    <beans:property name="pubSubDomain" value="false" />
    <beans:property name="connectionFactory" ref="cachingConnectionFactory"></beans:property>
</beans:bean>

查看您的JNDI查找

<beans:bean id="jmsConnectionFactory" 
       class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="jms/TesService"/>
    <beans:property name="resourceRef" value="false"/>
    <beans:property name="lookupOnStartup" value="false"/>
    <beans:property name="cache" value="true"/>
    <beans:property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
</beans:bean>

首先,我建议使用jee名称空间进行查找,不要将lookupOnStartup设置为false。后者将延迟第一次接收/发送消息,因为仍然必须进行整个JNDI查找。

<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="jms/TesService" proxy-interface="javax.jms.ConnectionFactory" />

同样在您的代码中,您不需要MessageCreator默认情况下JmsTemplate会为TextMessage有效负载创建String

public void sendMessage(final String message, final String queueName) throws JMSException {
        MQQueue queue = new MQQueue(queueName);
        queue.setTargetClient(1);       

        long queueStartTime = System.currentTimeMillis();

        jmsTemplate.convertAndSend(queue, message);

        if(LOGGER.isInfoEnabled()) {
            LOGGER.info("Queue put time: " + (System.currentTimeMillis() - queueStartTime) + " queue: " + queue.getQueueName());
            LOGGER.info("Sent message to queue: " + queue.getQueueName() + " message: " + message);
        }
}

如果您想向javax.jms.Message添加其他标题或属性,请改用MessagePostProcessor