7

(私の意見では) スケールアップしていない DefaultMessageListenerContainer があります。コンテナは、100 個のメッセージが格納されているキューをリッスンするように定義されています。

コンテナが任意の長さになり、メッセージが可能な限り速く消費されることを期待します( maxConcurrentConsumers 構成を観察することにより)。だから私は、7つのconcurrentConsumersがあると仮定します。(コンテナの起動時に2つのconcurrentConsumersから開始)いくつかのログ情報:

activeConsumerCount: 5
concurrentConsumers: 2
scheduledConsumerCount: 5
idleConsumerLimit: 1
idleTaskExecLimit: 1
maxConcurrentConsumers: 7

私のSpring-config(その一部):

<bean id="abstractMessageListenerContainer" class="my.package.structure.LoggingListenerContainer" abstract="true">
    <property name="connectionFactory" ref="jmscfCee" />
    <property name="maxConcurrentConsumers" value="7"/>
    <property name="receiveTimeout" value="100000" />
    <property name="concurrentConsumers" value="2" />
</bean>

<bean class="my.package.structure.LoggingListenerContainer" parent="abstractMessageListenerContainer">
    <property name="destinationName" value="MY.QUEUE" />
    <property name="messageListener" ref="myMessageListener" />
</bean>

<bean id="myMessageListener" class="my.package.structure.ListenerClass"></bean>

マイ ロギング コンテナ

public class LoggingListenerContainer extends DefaultMessageListenerContainer{

private static final Logger logger = Logger
        .getLogger(LoggingListenerContainer.class);
@Override
protected void doInvokeListener(MessageListener listener, Message message)
        throws JMSException {

    logger.info("activeConsumerCount: " + this.getActiveConsumerCount());
    logger.info("concurrentConsumers: " +  this.getConcurrentConsumers());
    logger.info("scheduledConsumerCount: " + this.getScheduledConsumerCount());
    logger.info("idleConsumerLimit: " + this.getIdleConsumerLimit());
    logger.info("idleTaskExecLimit: " + this.getIdleTaskExecutionLimit());
    logger.info("maxConcurrentConsumers: " + this.getMaxConcurrentConsumers());
    super.doInvokeListener(listener, message);
}

私のリスナークラス:

public class ListenerClass implements MessageListener {


    public void onMessage(Message msg) {
           //Do some business function
    }

}

誰かが私の構成を修正したり、構成に関するヒントを教えたり、コンテナのアプローチを説明したりしてくれませんか? (私が何かを誤解していた場合)

スケーラビリティのトピックに関連する場合は、ActiveMQ (WebSphere MQ を使用した運用環境) を使用してローカルでテストしています。

編集:

<bean id="jmscfCee" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
        <property name="brokerURL">
            <value>${jmscfCee.hostName}</value>
        </property>
</bean>

<bean id="jmscfCeeCachingConnectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory ">
    <constructor-arg ref="jmscfCee" />
    <property name="sessionCacheSize" value="10" />
</bean>
4

1 に答える 1

5

場合によります。数年前に ActiveMQ で同様の問題が発生しました。そのデフォルトの動作は、大量 (数千) の小さなメッセージに対して非常に最適化されています。デフォルトでは、各コンシューマーは 1000 のバッチでメッセージをプリフェッチするため、メッセージの数が少ない場合、すべてが 1 つのコンシューマーのプリフェッチ バッファーに収まり、他のコンシューマーがアイドル状態のままになっていることに気付くでしょう。

この動作は、プリフェッチ ポリシーを使用して、接続 URI または Spring 構成のいずれかで調整できます (接続ファクトリの構築方法である場合)。

<amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost">
  <property name="prefetchPolicy">
    <amq:prefetchPolicy all="1" />
  </property>
</amq:connectionFactory>

当時私が使用していた ActiveMQ のバージョンは、0 のプリフェッチ制限をサポートしていませんでした (つまり、プリフェッチしないで、毎回ブローカーに行くだけです)。

于 2012-09-25T12:52:25.007 に答える