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

多个实例上的Spring任务和计划任务

袁晋鹏
2023-03-14

我们有一个Spring Boot应用程序,并有计划的任务。

我们希望在多个服务器上部署我们的应用程序,因此将有多个应用程序实例。

如何将 Spring 配置为仅在指定的服务器上运行计划任务?

共有3个答案

澹台华翰
2023-03-14

最好的选择之一-使用带有集群的Quartz调度程序。很简单,只是:

implementation("org.springframework.boot:spring-boot-starter-quartz")

并为带Spring的石英配置作业(请参阅教程)

application.yaml中的群集配置:

spring:
  datasource: ... # define jdbc datasource
  quartz:
    job-store-type: jdbc # Database Mode
    jdbc:
      initialize-schema: never # For clustering do not initialize table structure
    properties:
      org.quartz:
          scheduler:
            instanceId: AUTO #Default hostname and timestamp generate instance ID, which can be any string, but must be the only corresponding qrtz_scheduler_state INSTANCE_NAME field for all dispatchers
            #instanceName: clusteredScheduler #quartzScheduler
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX #Persistence Configuration
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #We only make database-specific proxies for databases
            useProperties: true #Indicates that JDBC JobStore stores all values in JobDataMaps as strings, so more complex objects can be stored as name-value pairs rather than serialized in BLOB columns.In the long run, this is safer because you avoid serializing non-String classes to BLOB class versions.
            tablePrefix: QRTZ_  #Database Table Prefix
            misfireThreshold: 60000 #The number of milliseconds the dispatcher will "tolerate" a Trigger to pass its next startup time before being considered a "fire".The default value (if you do not enter this property in the configuration) is 60000 (60 seconds).
            clusterCheckinInterval: 5000 #Set the frequency (in milliseconds) of this instance'checkin'* with other instances of the cluster.Affects the speed of detecting failed instances.
            isClustered: true #Turn on Clustering
          threadPool: #Connection Pool
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

注意initialize模式:永远不要-您需要自己为集群模式初始化它

查看官方脚本: https://github.com/quartz-scheduler/quartz/tree/master/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore
您可以通过 liquibase/flyway/等使用它,但删除 DROP ... 查询!这就是为什么在集群中我们不会自动初始化架构的原因。

参见quartz文档
参见spring boot文档quartz
查看文章和示例

何灼光
2023-03-14

Spring - ShedLock项目就是专门为实现这一目标而创建的。

依赖性-

<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>    

配置-

@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")

实施-

@Scheduled(cron = "0 0/15 * * * ?")
@SchedulerLock(name = "AnyUniqueName", 
  lockAtLeastForString = "PT5M", lockAtMostForString = "PT10M")
public void scheduledTask() {
    // ...
}

该设置将确保只有一个实例运行计划任务。

如果您只需要一个特定实例,则应运行调度程序任务,

您需要配置您的调度程序来使用属性文件,并像这样控制调度程序开关

@ConditionalOnProperty(
  value = "scheduling.enabled", havingValue = "true", matchIfMissing = true
)
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class SchedulingConfig {

现在,您需要在 application.properties 文件中为要从中运行 Schedular 的实例提供一个属性调度.enabled = true

点击此链接以完成实施。

曾航
2023-03-14

这是一个非常广泛的话题。有很多选择可以实现这一目标。

>

  • 您可以将应用程序配置为具有多个配置文件。例如,使用另一个配置文件“cron”。并使用此配置文件仅在一台服务器上启动应用程序。例如,在一个生产环境中,您有三台服务器(S1、S2、S3),然后您可以在S1上运行prod和cron(-Dspring.profiles.active=prod,cron)。在S2和S3上,只需使用prod profile(-Dspring.profiles.active=prod)。

    在代码中,您可以在调度程序类上使用@Profile(“cron”)。这样,它只会在 cron 配置文件处于活动状态时执行

    使用分布式锁。如果您的环境中有Zoo将,您可以使用它来实现分布式锁定系统。

    您可以使用一些数据库(mysql)并创建一个示例代码来获取其中一个表的锁并添加一个条目。无论哪个实例获得锁,都将在此数据库中创建一个条目并执行cron作业。您需要在代码中进行检查,如果getLock()成功,则继续执行。MySQL有LOCK TABLES等实用程序,您可以使用它来摆脱并发读/写。

    就我个人而言,选项2是最好的。

  •  类似资料:
    • 本文向大家介绍Spring计划任务用法实例详解,包括了Spring计划任务用法实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Spring计划任务用法。分享给大家供大家参考,具体如下: 一 点睛 从Spring3.1开始,计划任务在Spring中的实现变得异常的简单。只需要下面两步。 1 通过在配置类上注解@EnableScheduling来开启对计划任务的支持。 2 在要执行计划

    • 我需要使用将widows服务器的Scheduler任务中的几个计划任务转换为一个独立的应用程序。网 在过去,我用过石英。Net框架4。x、 基于不同调度器的多个长时间运行的任务存在一些小问题。 现在我正在使用。Net 5,我想知道是否有一种新的方式来安排任务,比如worker服务,或者使用Quartz更好、更灵活。网 因为我需要运行长时间的任务,从30到2小时,我需要创建一个定时的后台任务,使用系

    • 我想每天使用Spring Boot发送电子邮件,用户指定发送时间,我使用石英来安排我的工作。电子邮件的收件人有(id、emailAddress、截止日期)电子邮件将发送给截止日期=今天X...(用户指定X)。例如:用户指定X是1号,所以我们对明天有截止日期的人感兴趣。 第1天:应用程序向截止日期为今天1的人发送电子邮件。。第二天:我希望应用程序在第二天将电子邮件发送给新的收件人,但使用下面的代码,

    • 计划任务系统使用说明 新版计划任务为用户提供了以下功能 创建一个计划任务 修改一个计划任务 删除计划任务 查看一个namespace的所有计划任务 查看一个namespcae的某个计划任务详细内容 查看一个计划任务的执行状况 查看任务的日志 查看创建的计划任务列表和某个计划任务的详细信息。 点击计划任务v2,进入计划任务列表,在这里可以看到用户名下的所有计划任务,点击一个计划任务,可以看到该计划任

    • 我们有一个spring boot应用程序和计划任务。 我们希望 在多个服务器上部署我们的应用程序 ,因此应用程序的多个实例。 如何配置spring在同时运行的多个实例上运行调度任务? 例如:一个应用程序在上午12点部署在第一个服务器实例中,任务计划在12点运行。同一个应用程序部署在第二个服务器实例中,时间为凌晨12点03分,由于部署任务存在差异,因此也在凌晨12点33分开始执行相同的cron表达式

    • 我使用spring boot with@Scheduled已经有一段时间了,但是最近我发现有一个潜在的危险威胁,如下所述:我发现当应用程序运行和计划任务运行几次时,有很多线程等待但没有完成,这在thread stacktrace中显示为'kill-3'。为了清除可能导致此问题的任何内容,我做了一个完全虚设的任务: 这是我的日志: 20151102 11:54:50.660信息池-3-线程-2---