|
对于最新稳定版本,请使用Spring for Apache Kafka 4.0.4! |
线程安全
当使用并发消息监听器容器时,一个监听器实例会被所有消费者线程调用。 监听器因此需要是线程安全的,最好使用无状态监听器。 如果无法使您的监听器线程安全,或者添加同步会显著降低并发带来的好处,您可以使用以下几种技术之一:
-
使用
n容器与concurrency=1配合,并使用原型作用域的MessageListener组件bean,使得每个容器都获得自己的实例(这在使用@KafkaListener时是不行的)。 -
在
ThreadLocal<?>实例中保持状态。 -
具有单例作用域的监听器委托到在
SimpleThreadScope中声明的bean(或类似的作用域)。
To facilitate cleaning up thread state (for the second and third items in the preceding list), 自版本 2.2 起,监听器容器在每个线程退出时发布一个 ConsumerStoppedEvent。
您可以使用 ApplicationListener 或 @EventListener 方法移除 ThreadLocal<?> 实例或 remove() 个线程作用域的 bean。
请注意,SimpleThreadScope 不会销毁具有销毁接口(如 DisposableBean)的 bean,因此您应 destroy() 该实例 yourself。
| 默认情况下,应用程序上下文的事件多播器会在调用线程上触发事件监听器。 如果你将多播器更改为使用异步执行器,线程清理将不再生效。 |
关于虚拟线程和并发消息监听器容器的特别说明
Because of certain limitations in the underlying library classes still using synchronized blocks for thread coordination, applications need to be cautious when using virtual threads with concurrent message listener containers.
When virtual threads are enabled, if the concurrency exceeds the available number of platform threads, it is very likely for the virtual threads to be pinned on the platform threads and possible race conditions.
Therefore, as the 3rd party libraries that Spring for Apache Kafka uses evolves to fully support virtual threads, it is recommended to keep the concurrency on the message listener container to be equal to or less than the number of platform threads.
This way, the applications avoid any race conditions between the threads and the virtual threads being pinned on platform threads.