Java 如果在处理步骤中出现故障,如何使Spring cloud stream Kafka streams binder重试处理消息?
我正在使用Spring Cloud Stream处理卡夫卡流。在消息处理应用程序中,可能会产生错误。因此,不应再次提交和重试该消息 我的申请方法-Java 如果在处理步骤中出现故障,如何使Spring cloud stream Kafka streams binder重试处理消息?,java,apache-kafka-streams,spring-cloud-stream,event-driven-design,spring-cloud-stream-binder-kafka,Java,Apache Kafka Streams,Spring Cloud Stream,Event Driven Design,Spring Cloud Stream Binder Kafka,我正在使用Spring Cloud Stream处理卡夫卡流。在消息处理应用程序中,可能会产生错误。因此,不应再次提交和重试该消息 我的申请方法- @Bean public Function<KStream<Object, String>, KStream<String, Long>> process() { return (input) -> { KStream<Object, String> kt = input.flatMapValue
@Bean
public Function<KStream<Object, String>, KStream<String, Long>> process() {
return (input) -> {
KStream<Object, String> kt = input.flatMapValues(v -> Arrays.asList(v.toUpperCase().split("\\W+")));
KGroupedStream<String, String> kgt =kt.map((k, v) -> new KeyValue<>(v, v)).groupByKey(Grouped.with(Serdes.String(), Serdes.String()));
KTable<Windowed<String>, Long> ktable = kgt.windowedBy(TimeWindows.of(500)).count();
KStream<String, WordCount> kst =ktable.toStream().map((k,v) -> {
WordCount wc = new WordCount();
wc.setWord(k.key());
wc.setCount(v);
wc.setStart(new Date(k.window().start()));
wc.setEnd(new Date(k.window().end()));
dao.insert(wc);
return new KeyValue<>(k.key(),wc);
});
return kst.map((k,v) -> new KeyValue<>(k, v.getCount()));
};
}
@Bean
公共职能流程(){
返回(输入)->{
KStream kt=input.flatMapValues(v->Arrays.asList(v.toUpperCase().split(\\W+)));
KGroupedStream kgt=kt.map((k,v)->new KeyValue(v,v)).groupByKey(Grouped.with(Serdes.String(),Serdes.String());
KTable KTable=kgt.windowedBy(TimeWindows.of(500)).count();
KStream kst=ktable.toStream().map((k,v)->{
WordCount wc=新的WordCount();
wc.setWord(k.key());
wc.setCount(v);
wc.setStart(新日期(k.window().start());
wc.setEnd(新日期(k.window().end());
插入(wc);
返回新的KeyValue(k.key(),wc);
});
返回kst.map((k,v)->newkeyValue(k,v.getCount());
};
}
这里,如果DAO insert方法失败,则不应将消息发布到输出主题,并应重试处理同一消息
我们如何配置kafka streams binder来执行此操作?。非常感谢您的帮助。Spring Cloud Stream Kafka Streams binder本身在执行业务逻辑时不提供此类重试机制。但是,解决此用例的一种方法可能是将关键调用(
dao.insert()
)包装在本地定义的RetryTemplate
中。下面是一个可能的实现,它使用1秒的退避策略重试10次。如果您正在尝试此解决方案,请确保从主要业务逻辑中提取与RetryTemplate相关的通用代码。我还没试过这个,但应该能用
KStream<String, WordCount> kst =ktable.toStream().map((k,v) -> {
WordCount wc = new WordCount();
...
org.springframework.retry.support.RetryTemplate retryTemplate = new
RetryTemplate();
RetryPolicy retryPolicy = new SimpleRetryPolicy(10);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000);
retryTemplate.setBackOffPolicy(backOffPolicy);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.execute(context -> {
try {
dao.insert(wc);
}
catch (Exception e) {
throw new IllegalStateException(..);
}
});
return new KeyValue<>(k.key(),wc);
});
KStream kst=ktable.toStream().map((k,v)->{
WordCount wc=新的WordCount();
...
org.springframework.retry.support.RetryTemplate RetryTemplate=new
RetryTemplate();
RetryPolicy RetryPolicy=newsimpleretrypolicy(10);
FixedBackOffPolicy backOffPolicy=新的FixedBackOffPolicy();
退避政策。退避期(1000);
retryTemplate.setBackOffPolicy(backOffPolicy);
setRetryPolicy(retryPolicy);
retryTemplate.execute(上下文->{
试一试{
插入(wc);
}
捕获(例外e){
抛出新的非法状态异常(…);
}
});
返回新的KeyValue(k.key(),wc);
});
事件在重试dao insert操作10次后,如果仍然失败,将引发异常,该异常将终止应用程序,在这种情况下,将不会提交偏移量。在重新启动时,在修复了基础问题之后,应用程序仍应从此偏移量继续运行 嗨,RetryTemplate的执行方法中的“上下文”对象是什么?如何创建它?这是框架创建并传入的
RetryContext
。我们只是在应用程序中使用它作为lambda参数。您不需要显式地创建它,框架会处理它。