我正在学习使用kafka,我有两个服务,生产者和消费者。
生产者产生需要处理的消息(对服务和数据库的查询)。这些消息由消费者接收,它负责处理这些消息并将结果保存在数据库中
制作人
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
...
kafkaTemplate.send(topic, message);
消费者
@KafkaListener(topics = "....")
public void listen(@Payload String message) {
....
}
我希望所有消息都能由使用者正确处理。 在这种情况下,我不知道如何处理消费者方面的错误。例如,数据库可能被暂时禁用,无法处理某些消息。
在这些情况下该怎么办?
我知道责任属于消费者。 我可以重试,但是如果数据库已关闭,则可以连续重试几次,这似乎不是一个好主意。而且,如果我继续使用消息,索引会提高,并且会丢失无法正确处理的事件。
答案 0 :(得分:1)
您可以通过提交所读取记录的偏移量来控制kafka使用者。除非已提交偏移量,否则Kafka将继续返回相同的记录。您可以将偏移提交设置为手动,并根据业务逻辑的成功决定是否提交。请参阅下面的示例
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("enable.auto.commit", "false");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("foo", "bar"));
final int minBatchSize = 200;
List<ConsumerRecord<String, String>> buffer = new ArrayList<>();
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
buffer.add(record);
}
if (buffer.size() >= minBatchSize) {
insertIntoDb(buffer);
consumer.commitSync();
buffer.clear();
}
}
Consumer.commitsync()提交偏移量。
另请参阅kakfa使用者文档以了解使用者偏移量here。
答案 1 :(得分:0)
此链接非常有用https://dzone.com/articles/spring-for-apache-kafka-deep-dive-part-1-error-han
Spring提供了DeadLetterPublishingRecoverer类,该类执行正确的错误处理。