当前位置: 首页 > 知识库问答 >
问题:

只在一个服务器实例上激活Batch

宋铭
2023-03-14

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

有没有办法让批处理部署在两个实例中,并告诉tomcat或nginx在主服务器中启动批处理(而从服务器不运行批处理)。

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

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

提前谢谢你。

共有3个答案

李睿
2023-03-14

我确实实现了一个简单的BCM服务器功能,所有服务器都使用其唯一的IP注册(创建一个服务器表条目)。服务器需要在规定的时间内注册(例如10秒)。如果服务器未在时间内注册(上次更新时间戳

最后,我有一个有序的服务器条目表,可以唯一地定义注册服务器的任务。

它的实现非常简单,工作非常完美。之前我也考虑过Spring批处理作业共享功能,但我希望zu有一个更轻量级、更灵活的解决方案。

目前,我在所有需要实施批处理的项目中都使用了它。

岳枫
2023-03-14

如果您设计两个应用服务器实例同时运行同一个作业,那么按照设计,一个将成功创建作业实例,另一个将失败(这个失败可以忽略)。请参阅JobRepository的Javadoc。这是作业存储库的作用之一:在集群环境中充当防止重复作业执行的保护措施。

如果其中一台服务器停止,第二台服务器可以代表他启动批处理。nginx或tomcat(或其他技术)中是否有工具可以做到这一点?

我相信不需要这样的工具或技术。如果其中一台服务器在时间表上停机,另一台就可以接管并成功启动这项工作。

殳飞扬
2023-03-14

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

由于在两个VM中同时触发了两个计划的方法,因此在这两个VM中都添加一个随机延迟。这个答案有很多选项可以选择如何将触发延迟一段随机的时间。Spring@Scheduled annotation随机延迟

在方法内部,只有当作业尚未启动时(由另一个虚拟机)才运行作业。这可以通过一个新表来跟踪。

以下是此设计的伪代码

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

由于两个虚拟机彼此独立,因此数据库或某个公共文件位置应被用作两次运行之间同步的锁。

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

以下是一些文档: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

 类似资料:
  • 我有一个队列通道和一个带有轮询器的服务激活器,轮询器从该队列中读取数据。我希望配置为“我希望50个线程轮询该队列,每次轮询并返回消息时,在此线程上调用服务激活器指向的服务。” 该服务没有异步注释,但无状态,可以以并发方式安全运行。 下面的方法能做到吗?有没有其他首选的方法来实现这一点?

  • 带有服务工作者的网站,托管https://121eddie.github.io/并在Chrome 66.0中运行。3359.181 /索引。html在每次加载时正确跟踪以下注册 }); 第一次运行时,/serviceWorker。js执行“激活”事件,正确获取缓存名称并缓存文件 在第二次运行时,不会触发“激活”(没有日志跟踪,没有获取)。 在第三次运行中,甚至不再触发“抓取”。这意味着脱机请求不被

  • 我有一个Web服务,每个版本将有多个版本和多个类。我想在启动时动态创建服务激活器,这样我就可以减少配置量,从而更容易维护。开发人员可以放入一个新类,SI会自动拾取它。 我编码了一个Application Listener: 稍后在路由器中,我有以下代码: 但当路由器尝试路由时,我会出现以下错误: 我该怎么做?我需要动态创建服务激活器,并在以后将消息路由到这些激活器。 没有办法在ServiceAct

  • 是否有一种方法可以丢弃使用Spring Integration DSL方法定义的Spring Integration Service Activator中的消息? 更具体地说,假设下面的IntegrationFlow定义... 我发现,从返回似乎可以有效地结束流,但我不确定这是否是最优雅/正确的解决方案。如果这是推荐的解决方案,那很好。

  • 我在一个简单的POJO中配置了一个服务激活器,我想将其转换为Java DSL。 现在,我的Java DSL如下所示, 有一个带有服务激活器的POJO, 在XML中,相应的配置如下所示, 如何在Java DSL中调用ServiceActivator方法?我正在考虑使用,但参数应该是什么 在使用Java DSL时,是否有空通道的概念?如果是,我们如何指定

  • 我试图在新安装的ApacheFelix容器中使用pax日志。已安装以下捆绑包: 尝试启动bundle 39(Pax Logging-Service)会导致: 我手动检查了Pax日志API包(Pax-Logging-API-1.8.3.jar)——文件。我还检查了(pax-logging-API-1.8.3.jar)。部分以导出包开头: 组织。阿帕奇。阿瓦隆。框架记录器;用法:=“org.apach