我是春天和卡夫卡的新手。我有一个用例,可以从kafka主题中消费,然后使用事务生成器将其生成另一个主题(消息应该只处理一次)。我看到了关于该线程(https://github.com/spring-projects/spring-kafka/issues/645)的讨论,但是实现起来却没有什么不同。 我在侦听器容器工厂中设置了一个手动ack模式,然后使用kafkatemplate.executeinTransaction(aysnc send)发送给生产者后进行了确认,这与这个结果相同吗? 。由于发送异步,因此我不确定发送是否可以达到目的
也在上述问题645的上例中,何时真正发生对kafka代理的实际提交?(消费者请参见数据)。它是在提交间隔还是按记录进行记录?我试图了解实际的提交是在时间间隔/每条记录发生还是可以配置的?
答案 0 :(得分:1)
涉及消费者补偿提交有两种方法,一种是启用
enable.auto.commit is set to true
auto.commit.interval.ms // configuring time for commit intervals
另一种方法是通过确认手动提交偏移
@KafkaListener(topics="${kafka.consumer.topic}", containerFactory="kafkaListenerContainerFactory", groupId="${kafka.consumer.groupId}")
public void taskListner(Task task, Acknowledgment Ack) {
//System.out.println(task.toString());
log.info(task.toString());
Ack.acknowledge();
}
在每个轮询间隔中调用使用者自动检查,并检查经过的时间是否大于配置的时间,如果超过,它将提交偏移量
答案 1 :(得分:0)
如果您使用交易,则不应通过使用者提交抵销;相反,您应该使用生产者将偏移量发送到事务。
如果配置正确,则在侦听器退出时,侦听器容器将自动为您执行此操作。参见the documentation。
通过使用KafkaTransactionManager
配置侦听器容器,该容器将启动事务。事务KafkaTemplate
上的所有发送都将参与事务,并且当侦听器正常退出时,容器会将偏移发送给事务(并提交事务)。
请参阅Java executeInTransaction
...
/**
* Execute some arbitrary operation(s) on the operations and return the result.
* The operations are invoked within a local transaction and do not participate
* in a global transaction (if present).
* @param callback the callback.
* @param <T> the result type.
* @return the result.
* @since 1.1
*/
<T> T executeInTransaction(OperationsCallback<K, V, T> callback);
此类操作不会参与容器的交易。