我在Kafka有一个使用消费转换技术的应用程序,该应用程序具有一次精确的语义。 (交易的)产生阶段会产生关于同一主题的新消息,然后再使用该消息(transactionally = read_committed)。只有一个线程在执行此操作,并且可以确保在生产者的事务提交之后进行消费者轮询。现在,每轮消耗转换生产只有一个民意测验。
在运行测试用例时,有时可能会有其他生产者发送的消息(明确地)在我的生产者的事务提交之前发送。然后我会遇到以下情况:
尽管最后一轮的交易已成功提交,但我的单个民意调查语句仅返回此外来消息,而不返回我刚刚产生的消息。
交易消费者
最终地图消费者配置=新的LinkedHashMap <>(); ConsumerConfig.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,SERVER); ConsumerConfig.put(ConsumerConfig.CLIENT_ID_CONFIG,ID); ConsumerConfig.put(ConsumerConfig.GROUP_ID_CONFIG,GROUP_ID); ConsumerConfig.put(ConsumerConfig.ISOLATION_LEVEL_CONFIG,“ read_committed”); ConsumerConfig.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最新”); ConsumerConfig.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,“ false”); ConsumerConfig.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,“ 100”); ConsumerConfig.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class.getName()); ConsumerConfig.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class.getName());
交易产生者
最终地图producerConfig =新的LinkedHashMap <>(); producerConfig.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,SERVER); producerConfig.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG,ID); producerConfig.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName()); producerConfig.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
我的轮询超时为2秒
答案 0 :(得分:0)
为了理解轮询的工作原理,我们传递给poll()的参数是一个超时间隔,它控制如果使用者缓冲区中没有可用数据,poll()将阻塞多长时间。如果将其设置为0,则poll()将立即返回;否则,返回false。否则,它将等待指定的毫秒数以使数据从代理到达。因此,如果将轮询配置为0毫秒,并且数据缓冲区中没有数据,则不会接收任何数据。
您可能无法接收到最近产生的数据,这取决于您对生产者的配置。除非产生的消息没有其副本且基于acks参数,否则该消息将可供使用者使用。
例如:如果您将副本设置为3且acks = all,除非所有复制者都确认领导者他们已经收到了该消息,否则将不会使此消息可供消费者使用。
这个问题,您怎么知道您是否已读取整个分区,如果您的民意测验不再提供任何记录(假设其余所有工作正常),则表明您已使用了该主题的所有消息