いくつかの要件について、誰かに正しい方向を教えてもらいたい: サーバー全体で非同期の信頼できる通知を送信する必要がある メッセージの消費者は自由に購読/購読解除する 消費者は多数になる プロデューサーは1人になるサーバーがダウンしても通知は失われず、サーバーが再びアップすると送信されます。通知の数が多いことが予想される 使用されるスレッドの数は、できるだけ少なくする必要があります。
上記の(クレイジーな)要件を考慮して、activemq/jms を使用してこの問題を解決しようとしました。これは適切な方向のように見えますか?
上記を考えると: 1.耐久性のあるサブスクライバーとjmsメッセージとkahadbを使用しました。2 JMS プロデューサーの場合、解決策は簡単に見えます。3. 消費者側としては困っています。
を。私は春を持っていますが、消費者の動的なサブスクリプションとサブスクリプション解除が必要なため、jms:listener-container を使用できませんでした。これは不可能に思えたので、持っているすべてのリスナーに対して SimpleListenerContainer を作成します。これでよろしいでしょうか?b. SimpleListenerContainer で、clientId を設定します (これは耐久性に必要なものであるため)
super.setSubscriptionDurable(durable);
if (durable ) super.setClientId(clientId);
ここで、私は次のものを持っています。次の構成があるとします。
<bean id="messageBusReceiverConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="maxConnections" value="10"/>
<property name="maximumActive" value="500"/>
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="idleTimeout" value="0"/>
</bean>
10*500=5000 の並列コンシューマーが可能になると予想していました。これは、消費者が永続的でない場合に当てはまります。しかし、super.setClientId(clientId) (super は SimpleMessageListenerContainer) が使用される耐久性のあるコンシューマーの場合、10 回目の接続後に次のようになります。ネストされた例外は javax.jms.IllegalStateException: Setting clientID on a used Connection is not allowed です
したがって、セッションに SimpleMessageListenerContainer を使用して永続的なサブスクライバーを使用することはできず、接続に対してのみ使用できません。これは本当ですか?maxConnections=500 で maximumActive=1 にするのは理にかなっていると思いますか? これで問題は解決しますが... JMS は初めてですが、これはブローカーにとってやり過ぎのようです。
わかりました、私はまだ正しい方向に進んでいることを考慮して、私は今私の消費者/リスナーを動的に購読解除する必要があるので、そうします
container.stop();
container.destroy();
ここで、container は SimpleMessageListenerContainer です。container.destroy(); 呼び出されたときにいくつかの例外をスローします。それを呼び出す必要がありますか、それとも停止メソッドで十分ですか?
わかりました、これらの質問は恣意的であり、jms を知っていて (jms が正しい解決策である場合)、私のコードからほとんど何も与えていない人でさえ、おそらく答えるのが難しいことを知っています。私が正しい軌道に乗っているかどうかについて誰かが私に何らかのガイダンスを与え、提起された質問についてできる限り多くの情報を提供してくれることを期待しています。