5

現在、リクエスト/レスポンス jms コネクタを使用する Mule ESB サーバー アプリケーションを構築しています。高度な同時実行環境で使用されているため、MQ 構成で spring jms キャッシュを有効にしました。

<spring:beans>
    <mule>
        <!-- MQ Factory -->
        <spring:bean id="testMsgMqFactoryBean1" name="testMsgMqFactory1" class="com.ibm.mq.jms.MQQueueConnectionFactory">
            <spring:property name="channel" value="${test.msg.mq.channel.1}" />
            <spring:property name="queueManager" value="${test.msg.mq.queueManager.1}" />
            <spring:property name="hostName" value="${test.msg.mq.hostName.1}" />
            <spring:property name="port" value="${test.msg.mq.port.1}" />
            <spring:property name="transportType" value="${mq.jms.transportType}" />
        </spring:bean>
        <spring:bean id="testMsgMqFactoryBeanCache1" class="org.springframework.jms.connection.CachingConnectionFactory">
            <spring:property name="targetConnectionFactory" ref="testMsgMqFactoryBean1" />
            <spring:property name="sessionCacheSize" value="${test.threading.profile.maxThreadsActive}" />
            <spring:property name="cacheConsumers" value="false" />
            <!-- <spring:property name="cacheProducers" value="false" /> -->
        </spring:bean>
        <!-- MQ Connector 1 -->
        <jms:custom-connector name="testMsgMqConnector.1" class="org.mule.transport.jms.websphere.WebsphereJmsConnector" doc:name="Custom JMS">
            <spring:property name="specification" value="1.1" />
            <spring:property name="connectionFactory" ref="testMsgMqFactoryBeanCache1" />
            <spring:property name="persistentDelivery" value="false" />
            <spring:property name="disableTemporaryReplyToDestinations" value="true" />
            <spring:property name="numberOfConsumers" value="${test.threading.profile.maxThreadsActive}" />
            <spring:property name="maxRedelivery" value="-1" />
            <receiver-threading-profile maxThreadsActive="${test.threading.profile.maxThreadsActive}" maxBufferSize="${test.threading.profile.maxBufferSize}" maxThreadsIdle="${test.threading.profile.maxThreadsIdle}"/>
            <reconnect frequency="${mq.jms.reconnection.frequency}" count="${mq.jms.reconnection.count}" blocking="false" />
        </jms:custom-connector>

        <!-- msgworks inbound and outbound MQ setup -->
        <!-- Rewards -->
        <jms:endpoint exchange-pattern="request-response" queue="${test.msg.mq.inbound.account.queue}" name="testQueue1" connector-ref="testMsgMqConnector.1" doc:name="JMS" />
    </mule>
</spring:beans>

この構成は、クライアントが静的な replyTo キューを使用する場合に正常に動作します。ただし、動的/一時的な ReplyTo キューを使用しているお客様もいます。はプロデューサをキャッシュするためorg.springframework.jms.connection.CachingConnectionFactory、一時的な replyTo キューごとにプロデューサ オブジェクトがキャッシュされ、閉じられることはありません。何百ものリクエストを処理した後、アプリケーションは例外をスローし始めました。

********************************************************************************
Message               : Failed to create and dispatch response event over Jms destination "queue://QMGR1/TESTret5a975v53AF980F2006BE02?targetClient=1". Failed to route event via endpoint: null. Message payload is of type: JMSTextMessage
Code                  : MULE_ERROR-42999
--------------------------------------------------------------------------------
Exception stack is:
1. MQJE001: Completion Code 2, Reason 2017 (com.ibm.mq.MQException)
  com.ibm.mq.MQQueueManager:2808 (null)
2. MQJMS2008: failed to open MQ queue TESTret5a975v53AF980F2006BE02(JMS Code: MQJMS2008) (javax.jms.ResourceAllocationException)
  com.ibm.mq.jms.MQQueueServices:398 (http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/jms/ResourceAllocationException.html)
3. Failed to create and dispatch response event over Jms destination "queue://QMGR1/TESTret5a975v53AF980F2006BE02?targetClient=1". Failed to route event via endpoint: null. Message payload is of type: JMSTextMessage (org.mule.api.transport.DispatchException)
  org.mule.transport.jms.JmsReplyToHandler:173 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)

MQ エラー コード (MQJE001: 完了コード 2、理由 2017) を調査した結果、このエラーの背後にある理由は、プロデューサーを閉じておらず、プロデューサーがキュー マネージャーの MQ ハンドルを使い果たしたためであることがわかりました。迅速かつ簡単な修正は、Spring jms キャッシュ構成の行のコメントを外して、毎回プロデューサーを閉じることです。

<spring:bean id="testMsgMqFactoryBeanCache1" class="org.springframework.jms.connection.CachingConnectionFactory">
    <spring:property name="targetConnectionFactory" ref="testMsgMqFactoryBean1" />
    <spring:property name="sessionCacheSize" value="${test.threading.profile.maxThreadsActive}" />
    <spring:property name="cacheConsumers" value="false" />
    <spring:property name="cacheProducers" value="false" />
</spring:bean>

現在、MQ の問題は見られませんが、別のパフォーマンスの問題が発生しました。プロデューサーがキャッシュされていないため、新しいプロデューサーが毎回作成されるためです。

私の質問は、このシナリオにどう対処するかです。クライアントは一時キューから応答メッセージを受信する方法を変更しないため、パフォーマンスに影響を与えずに MQ ハンドラーを使い果たすことを回避するにはどうすればよいでしょうか。

どうもありがとうございました - レイ

4

1 に答える 1

1

これは非常に興味深い使用例です。ただし、これを修正するためのすぐに使えるものは何もないのではないかと心配しています。より明白な解決策があります。キャッシングを無効にするか、スプリング キャッシュ プロバイダーを拡張します。

一時的なキューとパフォーマンスは、同時に持つことができる 2 つのことではありません。別の可能性を提案します:

一時キューを使用して、特定のコンシューマーのみに応答を返すようにしている場合、おそらく再接続時に古いメッセージを破棄することに加えて:

メッセージを受信するホスト名を含むヘッダーと、各コンシューマー ノードで異なるセレクター、および送信されたメッセージの TTL を組み合わせて、しばらくするとメッセージが消えるようにする、よく知られたキューを応答に使用できます。

于 2014-12-19T23:32:04.623 に答える