春季批处理 - 停止在不同 JRE 中运行的作业



背景:

我创建了一个停止作业,它查找具有指定名称的正在运行的作业,如下所示:

jobExplorer.findRunningJobExecutions("job_A")

然后,对于每次执行job_A,它都会调用:

jobOperator.stop(execution.getId());

问题

当我调用上面的stop()方法时;即使它最终实现了我想要的,但它仍然抛出一个异常:

WARN o.s.b.c.l.s.SimpleJobOperator [main] Cannot find Job object
org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [job_A] was registered
at org.springframework.batch.core.configuration.support.MapJobRegistry.getJob(MapJobRegistry.java:66) ~[spring-batch-core-3.0.6.RELEASE.jar:3.0.6.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobOperator.stop(SimpleJobOperator.java:403) [spring-batch-core-3.0.6.RELEASE.jar:3.0.6.RELEASE]

原因

stop()方法尝试在JobRegistry中找到job_A时,会发生这种情况。

因此,即使job_A是在"JobRepository"中找到的,因为存储库在数据库中查找,但在"JobRegistry"中找不到它,这是在其运行时环境中创建的作业 bean 的本地缓存,因为job_A正在运行不同的运行时实例,它没有被注册并抛出和错误。

关注

即使工作"A"停止,我仍然担心由于异常而错过了什么。

我已经搜索了这个问题,只找到了有关如何停止作业的一般答案,但是我没有找到任何人解释如何停止另一个运行时的正在运行的作业。

任何答案将不胜感激。

JobOperator

并非旨在像您尝试的那样编排分布式批处理环境。 您实际上有两个选择:

  1. 直接使用JobRepository-导致作业在远程 JVM 中成功停止的部分是更新JobRepository,并且另一个 JVM 中正在运行的作业知道定期检查。 无需使用JobOperator来完成此操作,只需直接使用JobRepository进行更新即可。
  2. 使用更强大的编排工具,如Spring Cloud Data Flow - 这种针对作业的编排(部署、启动、停止等)(通过 Spring Cloud Task)是 Spring Cloud Data Flow 的用途。

您可以在网站上阅读有关Spring Cloud Data Flow的更多信息:https://cloud.spring.io/spring-cloud-dataflow/

除了Michael提到的之外,您还可以通过向应用程序添加一些接口来解决此问题,该接口允许您传递命令来启动或停止作业。类似于网络服务的东西。公开端点以阻止它。现在,在这种情况下,在集群系统中处理可能有点棘手。

最新更新