【问题标题】:JmsTemplate and CachingConnectionFactoryJmsTemplate 和 CachingConnectionFactory
【发布时间】:2015-03-06 11:18:41
【问题描述】:

在向 Jboss 队列发送消息时尝试减少连接和会话创建时遇到了一些困难。

<bean name="jbmTemplate-${jbmQueue}" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
        <property name="sessionTransacted" value="true" />

    <!-- connection factory -->
    <property name="connectionFactory">
        <ref bean="jbmCachingConnectionFactory"/>
    </property>

    <property name="pubSubDomain">
        <value>false</value>
    </property>

    <property name="receiveTimeout">
        <value>${jmsReceiveTimeout}</value>
    </property>

</bean>

我正在使用 JmsTemplate 发送消息:

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

jbmConnectionFactory 定义如下:

<jee:jndi-lookup id="jbmConnectionFactory" jndi-name="XAConnectionFactory"
        resource-ref="true" lookup-on-startup="false" proxy-interface="javax.jms.ConnectionFactory"
        cache="false">
    <jee:environment>
        java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
        java.naming.provider.url=${jbmURL}
        java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
    </jee:environment>
</jee:jndi-lookup>

我正在使用这段代码向 Jboss 发送消息:

public void send(final Serializable payload, final String correlationId) {
    log.debug("payload: {}", payload);

    try {
        jmsQueueTemplate.send(destinationName, new MessageCreator() {
            public Message createMessage(Session session)
                    throws JMSException {
                ObjectMessage msg = session.createObjectMessage(payload);

                msg.setJMSType(payload.getClass().getCanonicalName());
                msg.setJMSCorrelationID(correlationId);

                return msg;
            }

        });
    } catch (Exception e) {
        log.error("Couldn't send message");
        throw new BlockingException(e);
    }
}

我试图通过使用 CachingConnectionFactory 来避免创建和关闭我发送的每条消息的连接和会话,但据我所知,在使用 JmsTemplate 时,无论我使用什么类型的 connectionFactory,连接会话将永远终止:

finally {
            JmsUtils.closeSession(sessionToClose);
            ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
        }

我是否调用了错误的方法?有什么我不明白的吗?

【问题讨论】:

    标签: jboss jms spring-jms jmstemplate


    【解决方案1】:

    CachingConnectionFactory 为忽略close() 的连接返回代理(包装器)。同样,session.close() 被拦截,会话被放入缓存中,而不是真正关闭它。

    事实上,它要求会话“关闭”,以便会话可供下次使用。

    您可能需要配置缓存大小(默认情况下只有 1;请参阅javadocs)。

    【讨论】:

    • 嗨@Gary,我已经配置了缓存大小并将其增加到10,但问题仍然存在。我看到的是,当我们在执行内部的“doGetTransactionalSession”方法中时:Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession( getConnectionFactory(), this.transactionalResourceFactory, startConnection); 当他创建一个新的`resourceHolderToUse = new JmsResourceHolder(connectionFactory); ` 他创建了一个内部没有连接的 JmsResourceHolder,因此他继续创建它。
    • 对,但由于CachingConnectionFactory 只有一个连接(它是SingleConnectionFactory 的子类),所以他获得了相同的连接。
    • 这很奇怪,因为我正在排队消息,同时监视接收机器上的连接,我看到每次我将消息排队时,连接数都会上升(然后又下降过了一会儿)。它是否按预期工作?谢谢
    • 否;您的配置一定有问题 - CCF 只有一个连接。如果启用 TRACE 日志记录,您将获得大量信息。
    • @Gary 如果连接工厂由容器中的 JCA 管理,那么最好的方法是什么。我对缓存有某种类似的担忧。 JCA的缓存机制不会是多余的吗?我发布了问题(stackoverflow.com/questions/28844426/…,我会很感激你的观点。谢谢
    猜你喜欢
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2019-07-28
    • 1970-01-01
    • 2021-01-16
    • 2011-08-20
    相关资源
    最近更新 更多