过去,我做出了错误的决定,那就是在一个线程中操作多个使用者(相同的组ID),但是当时没有相应的使用情况,所以这个问题没有被发现。
现在,我意识到当我有多个使用者时,我的程序会出错,查询相应的信息,再加上自己的测试,我得到了这三种情况。
我想我知道如何更改它,但是我不知道为什么,卡夫卡消费者在线程中存储什么样的东西会导致这种情况。
我的代码就是这样
Properties properties = new Properties();
properties.setProperty(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, "3000");
properties.setProperty(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "30000");
properties.setProperty(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, "30000");
properties.setProperty(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "500");
properties.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "shoothzj.group");
properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
return properties;
private Map<String, KafkaConsumer<String, T>> consumerMap = new HashMap<>();
for (KafkaConsumer<String, T> consumer :consumerMap.values()) {
consumer.poll(1000);
//handle it
}
答案 0 :(得分:1)
在同一线程中不能有多个使用者具有相同的组ID。以下是Kafka: The Definitive Guide
您不能同时有多个属于同一组的消费者 线程,您不能让多个线程安全地使用同一线程 消费者。每个线程一个使用者是规则。运行多个 同一应用程序中同一组中的使用者,您将需要运行 每个都有自己的线程。将使用者逻辑包装在 自己的对象,然后使用Java的ExecutorService启动多个对象 每个线程都有自己的使用者。合流博客有一个 教程展示了如何做到这一点。
我们在其中一项设计中遇到了类似的问题,并且以艰难的方式学习了我们的课程。如果我正确地记住了根本原因,那就是这样的。假设在同一线程中有两个使用者。如果第一次轮询之后的处理花费了很长的时间,则第二个使用者可能无法将心跳发送到 groupcoordinator ,因为心跳的发送发生在 poll( )方法,这将触发重新平衡,这将导致类似死锁的情况。因此,您的两个消费者都将陷入困境,等待重新平衡完成。