当前位置: 首页 > 知识库问答 >
问题:

Apache Camel Spring Boot-处理路由后优雅地关闭应用程序

高吉星
2023-03-14

我在Spring Boot应用程序中有两条路由(路由1和路由2)。我一直在研究如何在处理这两条路由后优雅地关闭应用程序。我参考了文档(https://camel.apache.org/manual/latest/gracefule-shutdown.html),但无法成功实现所需的功能。也许我的理解是错误的。

下面是我的两条路线

路线1

 from("timer://runOnce?repeatCount=1")
     .to("{{sql.selectAll}}")
......... SOME PROCESSING
     .to("direct:checkStatus")

路线2

from("direct:checkStatus")
     .delay(5000)
     .loopDoWhile(CONDITION)
          .process(DO_SOMETHING)
     .end()
     .to("jpa:com.pqr.MyClass)
     .stop();
camel.springboot.duration-max-seconds = 60

它会优雅地关闭两条路由,但随后会警告强制关闭ExecutorsService并且它不会停止主线程以停止应用程序。

2020-03-01 18:28:25.507  WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager     : Forcing shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService@17fbfb02[CamelSpringBootTerminateTask] due first await termination elapsed.
2020-03-01 18:28:25.507  WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager     : Forcing shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService@17fbfb02[CamelSpringBootTerminateTask] due interrupted.
2020-03-01 18:28:25.508  INFO 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager     : Shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService@17fbfb02[CamelSpringBootTerminateTask] is shutdown: true and terminated: false took: 10.004 seconds.
2020-03-01 18:28:25.508  WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager     : Forced shutdown of 1 ExecutorService's which has not been shutdown properly (acting as fail-safe)
2020-03-01 18:28:25.508  WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager     :   forced -> org.apache.camel.util.concurrent.SizedScheduledExecutorService@17fbfb02[CamelSpringBootTerminateTask]

2.从路由启动关机2

    from("direct:checkStatus")
            .delay(5000)
            .loopDoWhile(CONDITION)
                 .process(DO_SOMETHING)
            .end()
            .to("jpa:com.pqr.MyClass)
            .process(exchange -> {
                exchange.getContext().getRouteController().stopRoute("route1");
                exchange.getContext().getRouteController().stopRoute("route2");
                System.out.println("Route1 -->"+exchange.getContext().getRouteController().getRouteStatus("route1"));
                System.out.println("Route2 -->"+exchange.getContext().getRouteController().getRouteStatus("route2"));
                exchange.getContext().shutdown();
            });

“Route1”已正常停止,但“Route2”无法正常停止,并在等待默认超时(300s)。

2020-03-01 18:35:29.113  INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy   : Starting to graceful shutdown 1 routes (timeout 300 seconds)
2020-03-01 18:35:29.116  INFO 30504 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy   : Route: route1 shutdown complete, was consuming from: timer://runOnce?repeatCount=1
2020-03-01 18:35:29.116  INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy   : Graceful shutdown of 1 routes completed in 0 seconds
2020-03-01 18:35:29.117  INFO 30504 --- [read #4 - Delay] o.a.c.s.boot.SpringBootCamelContext      : Route: route1 is stopped, was consuming from: timer://runOnce?repeatCount=1
2020-03-01 18:35:29.117  INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy   : Starting to graceful shutdown 1 routes (timeout 300 seconds)
2020-03-01 18:35:29.118  INFO 30504 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy   : Waiting as there are still 1 inflight and pending exchanges to complete, timeout in 300 seconds. Inflights per route: [route2 = 1]

看起来有一个挂起的exchange邮件要消耗。我是否需要手动清除/使用exchange邮件以清除并促进优雅的关机?

这两个选项都不会停止主应用程序。我必须编写自定义关闭策略而不是DefaultShutdownStrategy来实现这一点吗?有人能好心地指出一个例子关闭Spring Boot应用程序后完成路由吗?提前致谢!!!

共有1个答案

蓟捷
2023-03-14

是否尝试使用Exchange.GetContext().stop()停止主应用程序

若要强制停止路由而不等待默认超时,可以使用Exchange.GetContext().StopProute(routeId,1L,TimeUnit.seconds);或以秒为单位设置超时Context.GetShutDownStrategy().SetTimeout(30);

 类似资料:
  • 我有一个使用可执行jar文件运行的Spring Boot应用程序。目前,为了停止服务,我们只是扼杀了进程。我看到我们可以使用以下方法优雅地关闭应用程序。 然后我可以在代码的某个地方调用或者我们可以使用下面的静态方法。 它目前适用于我们,但我们实际上是在一个控制器内部调用这个方法,如下所示。 当我们通过http访问这个controller方法时,应用程序将正常关闭。但我们不想这样做。是否可以编写一个

  • 优雅关闭,包括两部分,一个是 RPC 框架作为客户端,一个是 RPC 框架作为服务端。 作为服务端 作为服务端的时候,RPC 框架在关闭时,不应该直接暴力关闭。在 RPC 框架中 com.alipay.sofa.rpc.context.RpcRuntimeContext 在静态初始化块中,添加了一个 ShutdownHook // 增加jvm关闭事件 if (RpcConf

  • 在我的webapp中,我创建了一个使用具有固定大小线程池的的服务。我在整个应用程序生命周期中重用相同的。 All在Tomcat中运行,在关闭时出现以下错误: 我确实意识到在关闭tomcat之前需要关闭ExecutorService。Soms所以线程已经谈到了这一点,但我找不到一个干净的方法来处理这一点。 我是否应该使用,就像@tim-bender建议的那样,在优雅地关闭线程和执行器?还是应该使用C

  • Dorado的优雅关闭通过ShutDownHook方式实现,调用端和服务端通过添加hook进行资源的清理和关闭 protected synchronized void addShutDownHook() { if (hook == null) { hook = new ShutDownHook(this); Runtime.getRuntime().addS

  • 我有一个应用程序运行在嵌入式jetty服务器上。现在我想将服务器作为服务启动/停止。我使用一个脚本来启动服务器。

  • Graceful shutdown When you deploy a new version of your application, you must replace the previous version. The process manager you’re using will first send a SIGTERM signal to the application to noti