2012-01-20 135 views
1

我需要向/從單個JMS服務器上存儲的不同主題發送/接收消息。Spring JMS連接:性能考慮事項

我想使用JmsTemplate發送和MessageListenerContainer註冊異步監聽器。

我的配置是這樣的:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
    <property name="environment"> 
     <props> 
      <prop key="java.naming.factory.initial">xxx</prop> 
      <prop key="java.naming.provider.url">yyy</prop> 
     </props> 
    </property> 
</bean> 
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiTemplate" ref ="jndiTemplate"/> 
     <property name="jndiName" value="TopicConnectionFactory"/> 
    </bean> 

    <bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> 
     <constructor-arg ref="connectionFactory"/> 
    </bean> 

    <bean id="tosJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 
     <property name="connectionFactory" ref="singleConnectionFactory"/> 
     <property name="destinationResolver" ref="destinationResolver"/> 
     <property name="pubSubDomain" value="true"/> 
    </bean> 

據我瞭解,singleConnectionFactory,總是返回相同的連接實例,有助於減少創建和每次關閉 連接的jmsTemplate需要的開銷(例如)發送/接收消息(如使用正常的ConnectionFactory時那樣)。

我的第一個問題是:如果我創建了多個jmsTemplate(s),他們都可以共享一個參考singleConnectionFactory?或者他們是否每個都需要接收一個不同的實例(singleConnectionFactory1singleConnectionFactory2等)?

讀API爲SingleConnectionFactory,我發現這一點:

需要注意的是春天的消息偵聽容器相互支持監聽器容器實例中使用的共享Connection 。組合使用SingleConnectionFactory只對跨多個偵聽器容器共享單個JMS連接確實有意義。

這聽起來有點神祕。據我所知,每個MessageListenerContainer只能註冊1個Listener,所以我不明白連接共享的程度。

假設我想寄存器N聽衆:我需要重複N次這樣的事情:

<bean 
    class="org.springframework.jms.listener.SimpleMessageListenerContainer"> 
    <property name="connectionFactory" ref="connectionFactory" /> 
    <property name="destinationName" value="destX" /> 
    <property name="messageListener" ref="listener1outOfN" /> 
</bean> 

有多少個連接在這種情況下,從connectionFactory的創造?每個ListenerContainer或只有一個連接池?如果我提供SimpleMessageListenerContainer -s的參考號碼singleConnectionFactory

在這種情況下,最好的方法是什麼(從演出的角度來看)?

回答

5

如果我創建多個jmsTemplate(s),它們都可以共享一個ref到一個singleConnectionFactory嗎?

是的,這很好。 javadoc SingleConnectionFactory說:

根據JMS連接模型,這是完全線程安全的(與例如JDBC相反)。

JMS連接對象是線程安全的,可以被多個線程併發使用。所以沒有必要使用多個SingleConnectionFactory豆。

據我所知,有可能每MessageListenerContainer註冊只有1監聽器,所以我不明白是連接共享什麼程度。

這是真實的;但是,每個MessageListenerContainer可以同時具有多個線程處理消息,全部使用相同的MessageListener對象。該MessageListenerContainer將使用一個單一的共享Connection對於所有這些線程(除非進行其他配置做)。

請注意,Spring的消息偵聽器容器支持在每個偵聽器容器實例中使用共享的Connection。組合使用SingleConnectionFactory只對跨多個偵聽器容器共享單個JMS連接確實有意義。

換句話說,如果你已經是一個MessageListenerContainer,然後SingleConnectionFactory是不必要的,因爲單個連接內部管理,以MessageListenerContainer。如果您有多個偵聽器容器,並且希望它們全部共享連接,則需要SingleConnectionFactory。另外,如果您想分享聽音和發送之間的連接,那麼您也需要SingleConnectionFactory

+0

嗨!謝謝回答!如果有裁判singleConnectionFactory創建SimpleMessageListenerContainer一樣,我得到以下異常: 「錯誤創建與名init方法的類路徑資源XXX調用定義‘org.springframework.jms.listener.SimpleMessageListenerContainer#0’失敗豆;嵌套的例外是不支持setExceptionListener呼叫代理共享連接設置在SingleConnectionFactory了「的ExceptionListener」屬性,而不是另外,....」 你知道,如果缺少的東西:org.springframework.jms.IllegalStateException。? – Federico