我正在写一个卡夫卡消费者。使用者的工作主要是创建多个数据库实体,并在处理有效负载后保存它们。我正在尝试编写代码来处理在使用数据时可能发生的错误。 为此,我可以想到两种选择(在春季生态系统中)
失败的消息需要再次处理。
在案例1中: 再次,我必须编写另一个@KafkaListner,它监听死信主题并处理消息。这里的问题是我无法控制如何启动重新处理流程。 (就像调度程序一样),因为KafkaListener会在死信主题中发布数据后立即开始处理数据。
在情况2中: 由于我可以编写REST端点或计划程序来尝试重新处理失败的消息,因此我对重新处理流程有更多控制权。 (这里我对使用哪个数据库感到困惑。关系式或一些键值存储)
我基本上遇到了设计难题,无法确定哪种方法在Spring生态系统中更好。
感谢您的答复。
答案 0 :(得分:0)
我认为使用Kafka是最好的解决方案。
因为KafkaListener将在死信主题中发布数据后立即开始处理数据。
您可以通过在该侦听器上将autoStartup
设置为false来控制行为,然后根据需要使用KafkaListenerEndpointRegistry
启动/停止侦听器:
registry.getListenerContainer(myListenerId).start();
或者,您可以使用自己的KafkaConsumer
(由消费者工厂创建)并轮询所需数量的记录,并在完成后关闭消费者。
答案 1 :(得分:0)
我同意Gary Russell的回答,您可以创建KafkaConsumer
实例并控制其生命周期。该类来自org.apache.kafka:kafka-clients
库。
在特定情况下,您可以添加Thread.sleep(schedulerDelay)
来实现计划。这是简化的示例:
@Component
class Scheduler() {
public void init() {
// create kafka consumer connected to your DLQ topic
}
public void run() {
try {
while (running) {
ConsumerRecords<String, String> records = consumer.poll(1000);
for (ConsumerRecord<String, String> record : records)
processRecordLogicGoesHere(record);
Thread.sleep(schedulerDelay);
}
} finally {
consumer.close();
}
}
}
schedulerDelay
应该被小心地拾取,以跟上传入的消息,并且不要让它们因Kafka的日志清理策略而丢失。
关于如何使用Kafka的官方API的教程很多,这里是其中之一:Introducing the Kafka Consumer
此外,您可能会在这里找到一些想法:Retrying consumer architecture in the Apache Kafka