[英]Spring Kafka Simple Producer and Consumer with Retries and DLQ
[英]How to implement retries on spring kafka producer?
我想设置 3 次重试。 这是我正在想象的,如果生产者完成了 3 次重试并且仍然没有发送消息,它应该 go 到本地主题(dlt)。
这就是我现在正在使用的东西。 这是配置
@Bean
public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
ConcurrentKafkaListenerContainerFactoryConfigurer configure,
ConsumerFactory<Object, Object> kafkaConsumerFactory,
KafkaTemplate<Object, Object> template) {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
configure.configure(factory, kafkaConsumerFactory);
factory.setErrorHandler(new SeekToCurrentErrorHandler(new DeadLetterPublishingRecoverer(template), new FixedBackOff(0L, 2)));
return factory;
}
这是主要应用程序
@SpringBootApplication
@EnableKafka
@Retryable(value = Exception.class, maxAttemptsExpression = "3",
backoff = @Backoff(delayExpression = "1000"))
public class KafkaApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(KafkaApplication.class, args);
TestBean testBean = context.getBean(TestBean.class);
while(true){
for (int i = 0; i < 50; i++) {
try{
Thread.sleep(5000);
} catch (Exception e){
System.out.println("exception" + e.getMessage());
}
testBean.send("This is message " + i);
}
context.getBean(Consumer.Listener.class).latch.await(60, TimeUnit.SECONDS);
}
}
这是听众
@KafkaListener(topics = AppConfiguration.topic, groupId = AppConfiguration.groupid, containerFactory = "kafkaListenerContainerFactory")
public void listen(@Payload String message, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
try{
System.out.println("Successfully Received: " + message + " (partition: " + partition + ")");
this.latch.countDown();
} catch (Exception e){
System.out.println("Error in sending record");
System.out.println(e);
e.printStackTrace();
}
如果只想重试 3 次,又不想太多组件冗余,可以选择使用 try catch 配合本地 Queue 实现。
最简单的方法是在发生错误后立即重试。 当然,很多时候你会想每隔几分钟重试一次。 这时候只需要将错误信息放入catch中的一个队列中,然后再从另一个方法中取出队列数据再发送即可。 不过也许kafka已经为你解决了这个问题,有些异常可以自动重试,建议你理解: https://kafka.apache.org/21/documentation.html#producerconfigs
下面是最简单的实现:
public void sendToKafka(String topic, String key, String value, Integer retryTimes) {
try {
kafkaTemplate.send(topic, key, value);
} catch (Exception e) {
//if retryTimes
if (retryTimes < 3) {
sendToKafka(topic, key, value, ++retryTimes);
}
}
}
如此处所述,Kafka 直接在其生产者中支持此配置。
但是,最好的方法是使用delivery.timeout.ms 、 request.timeout.ms和retry.backoff.ms属性的组合来控制在给定时间段内发生的重试次数,如文档中所述。
如果你使用的是 Spring Boot,你可以配置一个 bean 如下:
@Bean(name = "ProducerConfig")
public Map<String, Object> producerConfig() {
return Map.of(
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
bootstrapServers,
// Enable safely ordered retries
ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true",
ProducerConfig.ACKS_CONFIG, "all",
// Config number of retries
ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 5000,
ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, 200,
ProducerConfig.RETRY_BACKOFF_MS_CONFIG, 500
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.