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