1

単一の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なるたびに(通常を使用する場合のように)接続を作成および閉じるオーバーヘッドを削減できます。jmsTemplateConnectionFactory

私の最初の質問は、複数を作成した場合jmsTemplate、それらすべてがへの参照を共有できるsingleConnectionFactoryかどうかです。singleConnectionFactory1または、それぞれ個別のインスタンス( 、、など)を受け取る必要がありますsingleConnectionFactory2か?

のAPIを読んでSingleConnectionFactory、私はこれを見つけました:

Springのメッセージリスナーコンテナは、Connection 各リスナーコンテナインスタンス内での共有の使用をサポートしていることに注意してください。組み合わせて使用SingleConnectionFactory​​することは、複数のリスナーコンテナ間で単一のJMS接続を共有する場合にのみ実際に意味があります。

これは私には少し不可解に聞こえます。私の知る限り、登録できるリスナーは1つだけなMessageListenerContainerので、接続がどの程度共有されているのかわかりません。

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ごとに1つですか、それとも接続のプールだけですか?そして、SimpleMessageListenerContainer-sにへの参照を提供するとどうなりsingleConnectionFactoryますか?

この場合の最善のアプローチは(もちろん、パフォーマンスの観点から)何ですか?

4

1 に答える 1

6

複数のjmsTemplateを作成した場合、それらすべてがsingleConnectionFactoryへの参照を共有できますか?

はい、これで問題ありません。のjavadocは次のようにSingleConnectionFactory述べています。

JMS接続モデルによると、これは完全にスレッドセーフです(JDBCなどとは対照的です)。

JMS接続オブジェクトはスレッドセーフであり、複数のスレッドで同時に使用できます。SingleConnectionFactoryしたがって、複数のBeanを使用する必要はありません。

私の知る限り、登録できるリスナーは1つだけなMessageListenerContainerので、接続がどの程度共有されているのかわかりません。

これは本当です; ただし、それぞれMessageListenerContainerがメッセージを同時に処理する複数のスレッドを持つことができ、すべて同じMessageListenerオブジェクトを使用します。MessageListenerContainerは、これらすべてのスレッドで共有される単一のConnectionスレッドを使用します(他の方法で構成されている場合を除く)。

Springのメッセージリスナーコンテナは、各リスナーコンテナインスタンス内での共有接続の使用をサポートしていることに注意してください。組み合わせて使用SingleConnectionFactory​​することは、複数のリスナーコンテナ間で単一のJMS接続を共有する場合にのみ実際に意味があります。

つまり、単一の接続が内部で管理されているため、単一のMessageListenerContainerがあれば不要です。複数のリスナーコンテナがあり、それらすべてが接続を共有するようにしたい場合は、が必要です。また、あなたがそうするように、あなたが聞くことと送ることの間の接続を共有したいならば、それも必要です。SingleConnectionFactoryMessageListenerContainerSingleConnectionFactorySingleConnectionFactory

于 2012-01-20T14:46:59.880 に答える