简体   繁体   English

在tomcat中正常关闭春季批处理作业

[英]Shutting down spring batch jobs gracefully in tomcat

We run several spring batch jobs within tomcat in the same web application that serves up our UI. 我们在提供UI的同一Web应用程序中的tomcat中运行多个spring批处理作业。 Lately we have been adding many more jobs and we are noticing that when we patch our app, several jobs may get stuck in a STARTING or STARTED status. 最近,我们增加了更多的工作,并且我们注意到在对应用程序进行修补时,一些工作可能会陷入“开始”或“开始”状态。 Many of those jobs ensure that another job is not running before they start up, so this means after we patch the server, some of our jobs are broken until we manually run SQL to update the statuses of the jobs to ABANDONED or STOPPED. 这些作业中的许多作业确保启动前另一个作业未运行,因此这意味着在修补服务器后,某些作业将被破坏,直到我们手动运行SQL将作业的状态更新为ABANDONED或STOPPED为止。

I have read here that JobScope and StepScope jobs don't play nicely with shutting down. 我在这里已经读到,JobScope和StepScope作业在关闭时效果不佳。

That article suggests not using JobScope or StepScope but I can't help but think that this is a solved problem where people must be doing something when the application exits to prevent this problem. 该文章建议不要使用JobScope或StepScope,但我不禁要认为这是一个已解决的问题,在该问题中,人们必须在应用程序退出时采取某些措施以防止出现此问题。

Are there some best practices for handling this scenario? 是否有一些最佳实践来处理这种情况? What are you doing in your applications? 您在应用程序中做什么?

We are using spring-batch version 3.0.3.RELEASE 我们正在使用3.0.3版本的spring-batch。

I will provide you an idea on how to solve this scenario. 我将为您提供有关如何解决这种情况的想法 Not necessarily a spring-batch solution. 不一定是批量解决方案。

Everytime I need to add jobs in an application I do as this: 每当我需要在应用程序中添加作业时,我都会这样做:

  1. Create a table to control the jobs (queue, priority, status, etc.) 创建一个表来控制作业(队列,优先级,状态等)
  2. Create a JobController class to manage all jobs 创建一个JobController类来管理所有作业
  3. All jobs are defined by the status R -running, F -Finished, Q -Queue (you can add more as you need like aborted, cancelled, etc) (the jobs control these statuses) 所有作业均由状态R运行, FQ队列定义(您可以根据需要添加更多内容,如中止,取消等)(这些作业控制这些状态)
  4. The jobController must be loaded only once, you can define it as a spring bean for this jobController只能加载一次,您可以为此定义它作为一个Spring bean。
  5. Add a boolean attribute to JobController to inform if you already checked the jobs when you instantiate it. JobController添加一个布尔属性,以在实例化时通知您是否已经检查了作业。 Set it to false 将其设置为false
  6. Check if there are jobs with the R status which means that in the last stop of the server they were running so you update every job with this R status to Q and increase their priority so it will get executed first after a restart of the server. 检查是否存在具有R状态的作业,这意味着它们在服务器的最后一站正在运行,因此您将具有R状态的每个作业更新为Q并增加其优先级,以便在重新启动服务器后首先执行该作业。 This check is inside the if for that boolean attribute, after the check set it to true. 将该检查设置为true后,该检查位于该布尔属性的if中。

That way every time you call the JobController for the first time and there are unfinished jobs from a server crash you will be able to set then all to a status where it can be executed again. 这样,每次您第一次调用JobController时,由于服务器崩溃而有未完成的作业,您便可以将所有参数设置为可以再次执行的状态。 And this check will happens only once since you will be checking that boolean attribute. 由于您将检查该boolean属性,因此该检查仅会发生一次。

A thing that you should be aware of is caution with your jobs priority, if you manage it wrong you may run into a starvation problem. 您应该注意的一件事是谨慎处理工作优先级,如果处理不当,可能会遇到饥饿问题。

You can easily adapt this solution to spring-batch. 您可以轻松地将此解决方案改编为春季批处理。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM