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

在群集环境中创建Quartz触发器

仉姚石
2023-03-14

相关:Quartz群集-服务器启动时触发器重复

private void createOrUpdateJob(JobKey jobKey, Class<? extends org.quartz.Job> clazz, Trigger trigger) throws SchedulerException {
    JobBuilder jobBuilder = JobBuilder.newJob(clazz).withIdentity(jobKey);
    if (!scheduler.checkExists(jobKey)) {
        // if the job doesn't already exist, we can create it, along with its trigger. this prevents us
        // from creating multiple instances of the same job when running in a clustered environment
        scheduler.scheduleJob(jobBuilder.build(), trigger);
        log.error("SCHEDULED JOB WITH KEY " + jobKey.toString());
    } else {
        // if the job has exactly one trigger, we can just reschedule it, which allows us to update the schedule for
        // that trigger.
        List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
        if (triggers.size() == 1) {
            scheduler.rescheduleJob(triggers.get(0).getKey(), trigger);
            return;
        }

        // if for some reason the job has multiple triggers, it's easiest to just delete and re-create the job,
        // since we want to enforce a one-to-one relationship between jobs and triggers
        scheduler.deleteJob(jobKey);
        scheduler.scheduleJob(jobBuilder.build(), trigger);
    }
}
    null

这是很好的,但我担心的是,当两个实例完全同时启动时,可能会出现竞争情况。因为在这段代码周围没有全局锁,集群中的所有节点都将尊重它,如果两个实例同时联机,我可能会得到重复的作业或触发器,这就违背了这段代码的要点。

在集群环境中是否有自动定义Quartz作业和触发器的最佳实践?还是我需要自己设置锁?

共有1个答案

牛经赋
2023-03-14

我不确定是否有更好的方法在石英中做到这一点。但如果您已经在使用Redis或Memcache,我建议让所有实例对一个众所周知的键执行原子增量。如果粘贴的代码每小时每个群集只运行一个作业,则可以执行以下操作:

long timestamp = System.currentTimeMillis() / 1000 / 60 / 60;
String key = String.format("%s_%d", jobId, timestamp);

// this will only be true for one instance in the cluster per (job, timestamp) tuple
bool shouldExecute = redis.incr(key) == 1

if (shouldExecute) {
  // run the mutually exclusive code
}

时间戳为您提供了一个移动窗口,在该窗口中,作业正在竞争执行该作业。

 类似资料:
  • 问题内容: 我希望在我的应用程序中使用石英调度程序,因为我有一个集群环境,并且想保证每小时只能运行一个工作实例。我的问题是…我是否必须使用JDBC作业存储库或某种形式的作业数据“外部”存储库,以确保集群中只有一个实例在任何给定的时间运行该作业,或者对Quartz来说,还有更多的魔力我知道吗? 问题答案: 是的,您需要使用JDBC- JobStore或TerracottaJobStore来启用节点相

  • 我有一个有两个节点的集群,它连接到同一个数据库,还有一个调度作业,由Quartz调度程序每10分钟启动一次。在quartz.properties中设置。 我感兴趣的是,调度程序是否会为同一节点发出作业,直到每隔10分钟可到达该节点为止,或者它使用某种算法来确定哪个节点将执行该作业。 我在文档(http://www.quartz-scheduler.org/documentation/quartz-

  • 有没有办法在现有GKE集群中创建Composer环境而不产生新集群?

  • 我在WebSphere8.5.5上使用Quartz-2.2.3,在集群环境中,我有2个节点,每个节点上有3个JVM。 我正在应用程序启动时配置作业。 问题是作业在每个节点上配置一次,我希望它在两个节点上只配置一次,而不是每个节点上都配置一次。 我的配置如下: QuartzConfig.Properties: ApplicationContextListener:

  • 一、集群规划 这里搭建一个 3 节点的 HBase 集群,其中三台主机上均为 Regin Server。同时为了保证高可用,除了在 hadoop001 上部署主 Master 服务外,还在 hadoop002 上部署备用的 Master 服务。Master 服务由 Zookeeper 集群进行协调管理,如果主 Master 不可用,则备用 Master 会成为新的主 Master。 二、前置条件

  • 一、集群规划 这里搭建一个 3 节点的 Storm 集群:三台主机上均部署 Supervisor 和 LogViewer 服务。同时为了保证高可用,除了在 hadoop001 上部署主 Nimbus 服务外,还在 hadoop002 上部署备用的 Nimbus 服务。Nimbus 服务由 Zookeeper 集群进行协调管理,如果主 Nimbus 不可用,则备用 Nimbus 会成为新的主 Nim