KafkaConsumer is not safe for multi-threaded access

问题背景:
1.使用ScheduledExecutorService创建一个线程池
2.创建多个kafkaConsumer对象,用来接收不同主题的消息
3.使用线程池来操作不同的kafkaConsumer对象


问题原因:
KafkaConsumer是非线程安全的类,当使用多个线程操作同一个KafkaConsumer对象时就会引起这个错误。


分析:
假设现在有两个kafkaConsumer对象ka和kb;ScheduledExecutorService创建了一个线程池,里面包含2个线程T1和T2
然后把ka和kb接收消息的任务提交给线程池,让他周期性的执行这两个任务。
如果在任务里加入了线程对象相关的调试信息,会发现T1/T2与ka/kb的对应关系不是固定的,例如下面这样:
第一次:T1执行ka,T2执行kb
第二次:T1执行kb,T2执行ka


这就造成了:T1,T2这两个线程都对同一个对象ka进行了操作,虽然并不是同时执行的,但是对于kafka这个消息系统来说,偶发性的,他会发现有两个线程对相同的kafkaConsumer对象进行了操作,于是就发生了KafkaConsumer is not safe for multi-threaded access


解决办法:
1.线程与KafkaConsumer对象的对应关系是1:1
2.要保证线程与KafkaConsumer对象的关系是固定不变的,也就是说,一个线程始终都只能操作同一个KafkaConsumer对象且一个KafkaConsumer对象始终是由同一个线程来操作的。


注意:上面的解决办法就决定了,不能使用ScheduledExecutorService这个线程池来操作KafkaConsumer。因为线程池本来是为了共享而存在的,他在执行任务时,线程与任务的关系是不固定的,而KafkaConsumer要求的是固定的线程

你可能感兴趣的:(kafka)