Activate Batch on only one Server instance

不羁的心 提交于 2020-05-24 03:53:20

问题


I have a nginx loadbalancer in front of two tomcat instances each contains a spring boot application. Each spring boot application executes a batch that writes data in a database. The batch executes every day at 1am. The problem is that both instances execute the batch simultaniously which i don't want.

Is there a way to keep the batchs deployed in two instances and tell tomcat or nginx to start the batch in master server (and the slave server doesn't run the batch).

If one of the servers stops, the second server could start the batch on his behalf.

Is there a tool in nginx or tomcat (or some other technology) to do that ?

thank you in advance.


回答1:


Here is a simplistic design approach.

Since you have two scheduled methods in the 2 VMs triggered at same time, add a random delay to both. This answer has many options on how to delay the trigger for a random duration. Spring @Scheduled annotation random delay

Inside the method run the job only if it is NOT already started (by the other VM). This could be done with a new table to track this.

Here is the pseudo code for this design:

@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
     }
}

The database, or some common file location, should be used as a lock to sync between the two runs, since the two VMs are independent of each other.

For a more robust design, consider Spring Batch Spring Batch uses a database for its jobs (JobsRepository). By default an in memory datasource is used to keep track of running jobs and their status. In your setup, the 2 instances are (most likely) using their own in memory database. Multiple instances of Spring Batch can coordinate with each other as a cluster and one can run jobs, while the other actasa backup, if the jobsRepository database is shared. For this you need to configure the 2 instances to use a common datasource.

Here are some docs: 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




回答2:


If you design two app server instances to run the same job at the same time, then by design, one will succeed to create a job instance and the other will fail (and this failure can be ignored). See Javadoc of JobRepository. This is one of the roles of the job repository: to act as a safeguard against duplicate job executions in a clustered environment.

If one of the servers stops, the second server could start the batch on his behalf. Is there a tool in nginx or tomcat (or some other technology) to do that ?

I believe there is no need for such tool or technology. If one of the servers is down at the time of the schedule, the other will be able to take things over and succeed in launching the job.



来源:https://stackoverflow.com/questions/60216411/activate-batch-on-only-one-server-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!