小编典典

仅在一个服务器实例上激活批处理

spring-boot

我在两个tomcat实例的前面都有一个nginx负载均衡器,每个实例包含一个spring boot应用程序。每个spring
boot应用程序执行一个批处理,该批处理将数据写入数据库。该批处理每天凌晨1点执行。问题是两个实例同时执行我不想要的批处理。

有没有一种方法可以将批处理部署在两个实例中,并告诉tomcat或nginx在主服务器中启动该批处理(而从属服务器不运行该批处理)。

如果其中一台服务器停止,则第二台服务器可以代表他启动批处理。

Nginx或tomcat(或某些其他技术)中是否有工具可以做到这一点?

先感谢您。


阅读 298

收藏
2020-05-30

共1个答案

小编典典

这是一种简单的设计方法。

由于在同时触发的2个VM中有两个计划的方法,因此请为这两个VM添加一个随机延迟。这个答案有许多关于如何将触发延迟随机时间的选择。

在该方法内部,仅在尚未启动(由另一个VM)启动该作业时,才运行该作业。可以使用新表来跟踪此操作。

这是此设计的伪代码:

@Scheduled(cron = "schedule expression")
public void batchUpdateMethod() {
     //Check database for signs of job running now.
     if (job is not running){
         //update database table to indicate job is running
         //Run the batch job
         //update database table to indicate job is finished
     }
}

由于两个VM彼此独立,因此应该将数据库或某个公共文件位置用作锁定,以在两次运行之间进行同步。

对于更健壮的设计,请考虑使用Spring Batch Spring
Batch将数据库用于其作业(JobsRepository)。默认情况下,内存数据源用于跟踪正在运行的作业及其状态。在您的设置中,这两个实例(很可能)正在使用它们自己的内存数据库。如果共享JobsRepository数据库,Spring
Batch的多个实例可以作为一个群集彼此协调,一个实例可以运行作业,而另一个actasa备份可以运行。为此,您需要配置2个实例以使用公共数据源。

以下是一些文档:https :
//docs.spring.io/spring-batch/docs/current/reference/html/index-
single.html#jobrepository

https://docs.spring.io/spring-
batch/docs/current/reference/html/job.html#configuringJobRepository

2020-05-30