1

キューからメッセージを消費するための次の構成があります。タスク エグゼキューターが一度に 1 つのタスクのみを実行するようにする必要があるため、タスク エグゼキューターも次のように構成しました。

<bean name="jmsTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="1" />
    <property name="maxPoolSize" value="2" />
</bean>

タスク Executor を上記のように構成すると、一度に 10 個のメッセージが消費され (キューに大量のメッセージが流れます)、コンテナーはほぼ 10 ~ 15 分間メッセージのリッスンを停止します。私のコンテナーは次のように構成されています。

<bean id="queueContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="destination" ref="queue" />
    <property name="maxConcurrentConsumers" value="1" />
    <property name="idleTaskExecutionLimit" value="1" />
    <property name="idleConsumerLimit" value="5" />
    <property name="receiveTimeout" value="10000" />
    <property name="recoveryInterval" value="10000" />
    <property name="taskExecutor" ref="jmsTaskExecutor" />
    <property name="messageListener" ref="queueListener" />
    <property name="autoStartup" value="true" />
</bean>

少しグーグルで調べた後、ThreadPoolTask​​Executor の代わりに SyncTaskExecutor を使用しようとしましたが、taskExecutor を次のように構成しました。

<bean name="jmsTaskExecutor"
            class="org.springframework.core.task.SyncTaskExecutor" />

しかし、それはTomcatでメモリリークを引き起こしています.

メッセージを消費し、タスクが完了した後にのみタスクへのメッセージを処理する動作を実現する方法を教えてください。

キュー リスナー コードは次のとおりです。

public class QueueListener implements SessionAwareMessageListener<Message>{
 @override
 public void onMessage(Message msg,Session ses) throws JMSException{
 ....
 ....
 ....
 }
}
4

1 に答える 1

0

上記のようにタスク Executor を構成すると、一度に 10 個のメッセージが消費されます

これは、プリフェッチ サイズが 10 であることを示しています。したがって、メッセージを処理するスレッドが 1 つしかない場合でも、そのスレッドは一度に 10 個のメッセージを受け取ります。ブローカを 0 または 1 のプリフェッチ サイズ (ブローカの実装によって異なります) で開始すると、必要な「一度に 1 つのメッセージ」の動作が得られます。

たとえば、ActiveMQ を使用している場合は、プリフェッチ サイズの設定に関するこのリンクを参照できます。

メッセージの処理に時間がかかっている場合は、「onMessage」コードをさらに確認して、時間を費やしている可能性がある場所を特定する必要があります。

于 2013-05-18T21:47:08.887 に答える