使用弹簧集成确保jms消费者关闭的正确方法是什么?

时间:2012-05-03 06:38:11

标签: java jms spring-integration

我正在使用spring集成来调用活动mq另一端的服务。我的配置如下:

<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <constructor-arg>
            <bean class="org.apache.activemq.ActiveMQConnectionFactory"
                  p:brokerURL="${risk.approval.queue.broker}"
                  p:userName="${risk.approval.queue.username}"
                  p:password="${risk.approval.queue.password}"
                    />
        </constructor-arg>
        <property name="reconnectOnException" value="true"/>
        <property name="sessionCacheSize" value="100"/>
    </bean>

    <!-- create and close a connection to prepopulate the pool -->
    <bean factory-bean="jmsConnectionFactory" factory-method="createConnection" class="javax.jms.Connection"
          init-method="close" />

    <integration:channel id="riskApprovalRequestChannel"/>
    <integration:channel id="riskApprovalResponseChannel"/>

    <jms:outbound-gateway id="riskApprovalServiceGateway"
                          request-destination-name="${risk.approval.queue.request}"
                          reply-destination-name="${risk.approval.queue.response}"
                          request-channel="riskApprovalRequestChannel"
                          reply-channel="riskApprovalResponseChannel"
                          connection-factory="jmsConnectionFactory"
                          receive-timeout="5000"/>

    <integration:gateway id="riskApprovalService" service-interface="com.my.super.ServiceInterface"
                         default-request-channel="riskApprovalRequestChannel"
                         default-reply-channel="riskApprovalResponseChannel"/>

我注意到,使用此配置,消费者创建以从活动mq获取匹配请求永远不会关闭。每个请求都会增加消费者数量。

我可以通过添加

来阻止这种情况发生
<property name="cacheConsumers" value="false" />

到CachingConnectionFactory。

但是根据CachingConnectionFactory的java文档:

  

请注意,持久订阅者只有在逻辑上才会被缓存   关闭会话句柄。

这表明会话永远不会被关闭。

这是件坏事吗?有没有更好的方法来阻止消费者堆积?

干杯, 彼得

2 个答案:

答案 0 :(得分:3)

首先,你不需要你的工厂bean上的init方法 - 它什么都不做 - 会话工厂只有一个连接,并且调用close()就是no-op。 (CCF是SingleConnectionFactory的子类)。

二;缓存消费者是默认的;会话永远不会关闭,除非会话数超过sessionCacheSize(已设置为100)。

当在缓存的会话上调用close()时,它会被缓存以供重用;这就是缓存连接工厂 的原因 - 避免了为每个请求创建会话的开销。

如果您不希望缓存会话,生产者和使用者的性能优势,请改用SingleConnectionFactory。请参阅JavaDoc for CachingConnectionFactory。

答案 1 :(得分:0)

使用cachingConnectionFactory时,以下是否有效?

在你的spring配置文件中添加连接工厂配置详细信息,如下所示:cacheConsumers="false"

默认行为是 true ,这导致队列中的连接泄漏。

相关问题