Mus*_*ice 6 java race-condition quartz-scheduler
我正在使用 Quartz Scheduler 来管理基于 java 的集群环境中的计划作业。在任何给定时间,集群中都有少量节点,它们都运行 Quartz,并由所有节点都连接到的 postgresql 数据库中的数据存储提供支持。
当实例初始化时,它会尝试通过执行以下代码来创建或更新 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);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法解决了许多问题:
这一切都很好,但我担心当两个实例同时启动时可能会出现潜在的竞争状况。由于此代码没有集群中所有节点都会遵守的全局锁,因此如果两个实例同时上线,我最终可能会得到重复的作业或触发器,这违背了此代码的要点。
是否有在集群环境中自动定义 Quartz 作业和触发器的最佳实践?或者我需要自己设置锁吗?
我不确定在 Quartz 中是否有更好的方法来做到这一点。但如果您已经在使用 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
}
Run Code Online (Sandbox Code Playgroud)
时间戳为您提供了一个移动窗口,在该窗口内作业竞争执行该作业。
| 归档时间: |
|
| 查看次数: |
3633 次 |
| 最近记录: |