此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring for Apache Kafka 3.2.1! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring for Apache Kafka 3.2.1! |
使用并发消息侦听器容器时,将在所有使用者线程上调用单个侦听器实例。 因此,侦听器需要线程安全,最好使用无状态侦听器。 如果无法使侦听器线程安全,或者添加同步会显著降低添加并发的好处,则可以使用以下几种方法之一:
-
将容器与原型作用域的 Bean 一起使用,以便每个容器都有自己的实例(这在使用 时是不可能的)。
n
concurrency=1
MessageListener
@KafkaListener
-
在实例中保留状态。
ThreadLocal<?>
-
让单例侦听器委托给在(或类似作用域)中声明的 Bean。
SimpleThreadScope
为了便于清理线程状态(对于前面列表中的第二项和第三项),从版本 2.2 开始,侦听器容器会在每个线程退出时发布一个。
您可以使用 or 方法使用这些事件,以从作用域中删除实例或线程范围的 Bean。
请注意,它不会销毁具有销毁接口的 bean(例如 ),因此您应该自己销毁实例。ConsumerStoppedEvent
ApplicationListener
@EventListener
ThreadLocal<?>
remove()
SimpleThreadScope
DisposableBean
destroy()
默认情况下,应用程序上下文的事件多播程序在调用线程上调用事件侦听器。 如果将多播程序更改为使用异步执行程序,则线程清理无效。 |
默认情况下,应用程序上下文的事件多播程序在调用线程上调用事件侦听器。 如果将多播程序更改为使用异步执行程序,则线程清理无效。 |
关于虚拟线程和并发消息侦听器容器的特别说明
由于仍然使用块进行线程协调的底层库类存在某些限制,因此应用程序在将虚拟线程与并发消息侦听器容器一起使用时需要谨慎。
启用虚拟线程时,如果并发超过可用的平台线程数,则虚拟线程很可能会固定在平台线程上,并可能存在争用条件。
因此,随着 Spring for Apache Kafka 使用的第三方库不断发展到完全支持虚拟线程,建议将消息侦听器容器上的并发性保持在等于或小于平台线程数。
这样,应用程序可以避免线程和固定在平台线程上的虚拟线程之间的任何争用条件。synchronized