Spring cloud Spring Cloud Stream Kafka-最终一致性-Kafka是否自动重试未确认的消息(使用autocommitoffset=false时)
实现最终一致的分布式体系结构是一件痛苦的事情。有大量的博客文章讲述了如何做到这一点,但没有展示(代码)如何实际做到这一点 我遇到的一个问题是,当消息未被确认时,必须手动重试消息 例如:我的订单服务向卡夫卡发送支付事件。支付服务已订阅并处理它,回答“支付确定”或“支付失败”Spring cloud Spring Cloud Stream Kafka-最终一致性-Kafka是否自动重试未确认的消息(使用autocommitoffset=false时),spring-cloud,microservices,distributed-transactions,spring-cloud-stream,spring-kafka,Spring Cloud,Microservices,Distributed Transactions,Spring Cloud Stream,Spring Kafka,实现最终一致的分布式体系结构是一件痛苦的事情。有大量的博客文章讲述了如何做到这一点,但没有展示(代码)如何实际做到这一点 我遇到的一个问题是,当消息未被确认时,必须手动重试消息 例如:我的订单服务向卡夫卡发送支付事件。支付服务已订阅并处理它,回答“支付确定”或“支付失败” 要求付款:订单服务----付款活动---->Kafka----付款活动---->付款服务 付款确认:->付款服务----付款确认事件---->Kafka----付款确认事件---->订单服务 支付失败->支付服务----支付失
订单服务----付款活动---->Kafka----付款活动---->付款服务
付款服务----付款确认事件---->Kafka----付款确认事件---->订单服务
支付服务----支付失败事件---->Kafka----支付失败事件---->订单服务
autocommitofset
属性设置为false,并处理消费者中的偏移确认:
@StreamListener(Sink.INPUT)
public void process(Message<?> message) {
Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class);
if (acknowledgment != null) {
System.out.println("Acknowledgment provided");
acknowledgment.acknowledge();
}
}
如果可以,如何在Kafka中配置重试期
在最坏的情况下(也是最有可能的情况下),这是不受支持的,我们必须手动重试。你知道使用Kafka处理最终一致性的Spring云流应用程序的真实例子吗
如果我们不执行acknowledge.acknowledge()会发生什么;卡夫卡会自动将该消息重新发送给该消费者吗
不会。只要客户端打开,卡夫卡消费者就会按顺序阅读消息。Kafka不支持更复杂的确认模式,例如单个消息确认,只更新给定消费者组和分区主题的偏移量。Spring Cloud Stream支持在Spring Cloud Stream中对异步处理的消息进行手动确认(从而防止消息丢失)——但假设消息一旦被手动确认,其偏移量就会被保存,因此来自同一分区主题的所有以前的消息都将被视为“已读”。如果您想挑出失败的消息,可以使用DLQ支持,并让后续消费者接收它们。重新启动使用者将从上次保存的偏移量恢复读取,因此您可以选择不为一系列处理失败的消息保存偏移量
Spring Cloud Stream使用者具有内置的重试和DLQ支持—请参阅中的enableDlq
,以及作为默认使用者属性的一部分提供的重试设置:
@Autowired
private PaymentBusiness paymentBusiness;
@StreamListener(Sink.INPUT)
public void process(Order order) {
Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class);
if (acknowledgment != null) {
paymentBusiness(order);
//If we don't get here because of an exception
//Kafka would retry...
acknowledgment.acknowledge();
}
}