スレッドセーフ

同時メッセージリスナーコンテナーを使用する場合、単一のリスナーインスタンスがすべてのコンシューマースレッドで呼び出されます。リスナーはスレッドセーフである必要があり、ステートレスリスナーを使用することをお勧めします。リスナーをスレッドセーフにすることができない場合、または同期を追加すると同時実行性を追加するメリットが大幅に減少する場合は、次のいずれかの手法を使用できます。

  • n コンテナーを concurrency=1 で使用し、プロトタイプスコープ MessageListener Bean を使用して、各コンテナーが独自のインスタンスを取得できるようにします (これは、@KafkaListener を使用する場合は不可能です)。

  • 状態を ThreadLocal<?> インスタンスに保持します。

  • シングルトンリスナーに、SimpleThreadScope (または同様のスコープ)で宣言されている Bean に委譲させます。

スレッド状態 (前のリストの 2 番目と 3 番目の項目) のクリーンアップを容易にするために、バージョン 2.2 以降、リスナーコンテナーは各スレッドが終了するときに ConsumerStoppedEvent を発行します。これらのイベントを ApplicationListener または @EventListener メソッドで使用して、スコープから ThreadLocal<?> インスタンスまたは remove() スレッドスコープ Bean を削除できます。SimpleThreadScope は、破棄インターフェースを持つ Bean ( DisposableBean など) を破棄しないため、インスタンスを自分で destroy() する必要があることに注意してください。

デフォルトでは、アプリケーションコンテキストのイベントマルチキャスタは、呼び出しスレッドでイベントリスナーを呼び出します。マルチキャスタを変更して非同期エグゼキュータを使用する場合、スレッドのクリーンアップは効果的ではありません。