Java 当使用带有Kafka的Spring Cloud Stream时,如何执行优雅的应用程序关闭?
我有一个springboot(v.1.57)应用程序,它使用springcloudstream(v1.3.0)和Kafka(v1.1.6)。我希望能够优雅地关闭它,也就是说,在关闭时,所有流侦听器(即,用@StreamListener注释)应该:Java 当使用带有Kafka的Spring Cloud Stream时,如何执行优雅的应用程序关闭?,java,spring-boot,apache-kafka,spring-cloud-stream,Java,Spring Boot,Apache Kafka,Spring Cloud Stream,我有一个springboot(v.1.57)应用程序,它使用springcloudstream(v1.3.0)和Kafka(v1.1.6)。我希望能够优雅地关闭它,也就是说,在关闭时,所有流侦听器(即,用@StreamListener注释)应该: 停止轮询新邮件 完成他们的工作 将偏移提交给卡夫卡 我注意到ContainerProperties中有一个名为“shutdownTimeout”的属性(默认设置为10000ms),因此我尝试通过反射将ConcurrentKafkAlisterConta
@Slf4j
@组成部分
公共类行为ConcurrentKafkaListenerContainerFactoryConfigurer扩展了ConcurrentKafkaListenerContainerFactoryConfigurer{
@自动连线
卡夫卡私人财产;
@凌驾
public void configure(ConcurrentKafkaListenerContainerFactory listenerContainerFactory,
消费者工厂(消费者工厂){
PropertyAccessor myAccessor=PropertyAccessorFactory.forDirectFieldAccess(此);
setPropertyValue(“properties”,kproperties);
ContainerProperties ContainerProperties=listenerContainerFactory
.getContainerProperties();
super.configure(listenerContainerFactory、consumerFactory);
containerProperties.setShutdownTimeout(30000);
}
}
但这并不成功。还尝试将它(shutdownTimeout:30000)放在application.yml的SpringCloudStreamBinder设置下,但同样没有帮助
有什么方法可以控制关机过程并实现我的目标吗?编辑
不再需要进行这种反射黑客;只需在应用程序上下文中添加一个ListenerContainerCustomizer。看
编辑\u结束
不再支持spring kafka 1.1.x;您应该在boot 1.5.x中使用1.3.9
当前的Boot 1.5.x版本是1.5.21
你应该立即升级
然而,所有这些项目都有更新的版本
SpringCloudStream不使用该工厂或引导属性来创建其容器;它不公开在容器上配置该属性的机制
SpringCloudStream2.1添加了ListenerContainerCustomizer
,它允许您通过设置绑定容器上的任何属性来定制绑定容器
我建议您升级到boot2.1.6和springcloudstreamgermantown(2.2.0)
编辑
这是一个有点黑客,但它应该工作,直到你可以升级到一个新的流版本
@springboot应用程序
@EnableBinding(Sink.class)
公共类SO56883620应用程序{
公共静态void main(字符串[]args){
run(So56883620Application.class,args.close();
}
专用最终倒计时闩锁=新倒计时闩锁(1);
@StreamListener(Sink.INPUT)
public void listen(字符串输入)抛出InterruptedException{
这个.latch.countDown();
系统输出打印项次(输入);
睡眠(6_000);
系统输出打印项次(“退出”);
}
@豆子
公共应用程序运行程序(KafkaTemplate模板){
返回参数->{
IntStream.range(0,2).forEach(i->template.send(“mytopic”,“foo”+i.getBytes());
//等待侦听器启动
这个.闩锁.等待(10,时间单位.秒);
System.out.println(“关闭”);
};
}
@豆子
公共SmartLifecycle bindingFixer(BindingService BindingService){
返回新的SmartLifecycle(){
@凌驾
公共int getPhase(){
返回Integer.MAX_值;
}
@凌驾
公共停车场(){
//无操作
}
@凌驾
公开作废开始(){
@抑制警告(“未选中”)
映射inputBinding=((列表)新的DirectFieldAccessor(inputBinding)
.getPropertyValue(“lifecycle.messageListenerContainer”))
.getContainerProperties().setShutdownTimeout(30_000L);
}
@凌驾
公共布尔值正在运行(){
返回false;
}
@凌驾
公共无效停止(可运行回调){
callback.run();
}
@凌驾
公共布尔值isAutoStartup(){
返回true;
}
};
}
}
我只是想说明一下,我使用的是Kafka v1.1.6,我没有使用spring Kafka(而是使用spring cloud stream,我想它在某种程度上使用了它)。我们计划在不久的将来(几个月后)升级到spring boot 2(无论它的最新版本是什么),但不幸的是我们现在无法做到。如果springcloudstream不允许我们配置该属性,那么还有其他方法可以执行正常关闭吗?可能使用另一种机制或自定义解决方案?不管怎样,您都需要覆盖流拉入的版本。使用start.spring.io创建的新1.5启动应用程序会自动执行此操作。我今天休息。我将试着看看下个星期是否有工作;我找到了一份工作——不过有点像黑客。请看编辑。谢谢Gary-我将用我的代码测试它,a将返回报告