24

spring、jms、activemq に基づいたシンプルなプロデューサーとコンシューマーのシミュレーションを作成しました。プロデューサーとコンシューマーの両方から高いパフォーマンスを達成しようとしています。

接続設定:

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
     <property name="connectionFactory"  ref="connectionFactory" />
</bean>

<amq:connectionFactory id="amqConnectionFactory" brokerURL="failover:(tcp://${broker.url}:61616)"  />

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

<amq:queue id="queue" physicalName="queue" />

<beans:bean id="jsonMessageConverter" class="XXXXX.converter.JsonMessageConverter" />

消費者設定:

<jms:listener-container concurrency="10"
    acknowledge="auto" prefetch="1" message-converter="jsonMessageConverter" transaction-manager="transactionManager"

    >
    <jms:listener id="queueListener_1" destination="ooIntegrationQueue"
        ref="myMessageListenerAdapter" />
</jms:listener-container>


<beans:bean id="myMessageListenerAdapter"
    class="org.springframework.jms.listener.adapter.MessageListenerAdapter" >
    <beans:property name="delegate" ref="consumer"/>
</beans:bean>


<beans:bean id="consumer" class="XXX.ConsumerImpl"/>

プロデューサー設定:

<beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
    p:connectionFactory-ref="connectionFactory" p:messageConverter-ref="jsonMessageConverter"
    p:defaultDestination-ref="ooIntegrationQueue" p:sessionTransacted="true" />

コンシューマーから始めて、毎秒約 25 のメッセージを消費することができましたが、これは非常に遅いです。少しグーグルで調べて構成をいじった後、トランザクションを使用しているという事実がボトルネックであることを発見しました。 DefaultMessageListenerContainer を自動配線し、キャッシュレベルを

listenerContainer.setCacheLevelName("CACHE_SESSION") 

私のパフォーマンスは、トランザクションが発生している間、毎秒約 1500 メッセージまで増加します。

私の問題は、1秒あたり約25回の操作でスタックしているプロデューサーにあり、プロデューサーのテストは簡単です:

int numOfMessages = getNumberOfMessages();


double startTime = System.currentTimeMillis();

for (int i = 1; i <= numOfMessages; i++) {
    jmsTemplate.convertAndSend("HelloWorld" + i);
}

double endTime = System.currentTimeMillis();

double totalTime=(endTime-startTime)/1000;
System.out.println("Time - "+totalTime+" seconds");
System.out.println("EPS - "+numOfMessages/totalTime);

システム全体のボトルネックになっているため、プロデューサーで同様のパフォーマンスを達成する方法を考えています。

4

4 に答える 4

16

元のポスターを助けるためにこの回答が遅れた場合は申し訳ありません。最近性能を調べJmsTemplateました。配信モードと受信確認モードが同じでも、ネイティブJMSコードは よりはるかに高速に見えましたJmsTemplateActiveMQ問題は、通常は非同期送信がデフォルトであることが判明しましたが、JmsTemplateそれを使用すると、代わりに同期送信が使用されます。これにより、パフォーマンスが大幅に低下します。ActiveMQConnectionFactoryuseAsyncSendプロパティをに設定しtrueて、非同期送信を強制することができます。詳細はこちら: JmsTemplate は悪ではない

于 2013-01-05T01:47:44.030 に答える
6

JMSTemplateは、ConnectionFactiory->接続->セッション-> MessageProducerのウォークを実行し、各送信後に各オブジェクトを閉じます。これを回避するには、amqConnectionFactory Beanをorg.apache.activemq.pool.PooledConnectionFactoryでラップし、CachingConnectionFactoryではなくテンプレートの下で使用します。

于 2011-08-15T19:49:42.290 に答える
1

確認方法を AUTO から CLIENT_ACKNOWLEDGE に変更してみてください。詳細については、仕様を参照してください。

于 2012-11-28T21:38:47.807 に答える
0

ActiveMQ のデフォルトの配信モードは何ですか? それは永続的なキューですか?もしそうなら、それはどのように構成されていますか? ブローカーはどのくらい離れていますか? これらの回答は、サーバーが送信を確認するのにかかる時間 (つまり、ネットワーク RTT + メッセージをディスクに同期的に永続化するための潜在的なコスト) を回答することによって、キューへの送信の基本的なコストを決定します。

もう 1 つの可能性は、送信ごとに新しい接続、セッション、およびメッセージ プロデューサーを実際に作成していることです。これは控えめに言ってもかなりの費用がかかります。基本的な健全性チェックとして、これが発生しているかどうかを確認する価値があります (たとえば、Spring にデバッグ ログを追加する、amq 管理コンソールで接続チャーンを確認する)。一見するとCachingConnectionFactory、デフォルトで単一のセッションとメッセージプロデューサーをキャッシュし、convertAndSend送信後に取得したセッションを閉じる必要があります。これにより、キャッシュされたセッションがプールに返されます。これは、次の送信時にキャッシュされたセッションを取得するのが比較的迅速であることを意味するはずです (Spring jms はメッセージを送信するためだけに非常に多くのコードを実行します)。

于 2011-08-15T14:48:54.203 に答える