我在两个tomcat实例的前面都有一个nginx负载均衡器,每个实例包含一个spring boot应用程序。每个spring boot应用程序执行一个批处理,该批处理将数据写入数据库。该批处理每天凌晨1点执行。问题是两个实例同时执行我不想要的批处理。
有没有一种方法可以将批处理部署在两个实例中,并告诉tomcat或nginx在主服务器中启动该批处理(而从属服务器不运行该批处理)。
如果其中一台服务器停止,则第二台服务器可以代表他启动批处理。
Nginx或tomcat(或某些其他技术)中是否有工具可以做到这一点?
先感谢您。
这是一种简单的设计方法。
由于在同时触发的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