我知道ShedLock可以用来做与Spring集成的分布式锁,如下所示:
@Scheduled(cron = "*/5 * * * * ?")
@SchedulerLock(name = "exampleLock", lockAtLeastForString = "20000", lockAtMostForString = "30000")
private void exampleMethod(){
System.out.println(String.format("[%s] test job runs...", new Date()));
}
但是对于我来说,我想执行多个计划任务(Crons),这些任务分别从数据库读取并由ThreadPoolTaskScheduler处理。我的编码如下,但是它不能处理多个实例来执行每个计划的任务。 Spring是否有办法实现这一目标?任何想法将不胜感激。
public class ExampleShedLock implements SchedulingConfigurer {
@Resource
private ScheduleTaskRepository scheduleTaskRepository;
@Resource
private TaskScheduler threadPoolTaskScheduler;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setTaskScheduler(getThreadPoolTaskScheduler());
Map<String, String> dataMap = scheduleTaskRepository
.selectExpressionByIsActive();
dataMap.forEach(
(key, expression) -> scheduledTaskRegistrar.getScheduler()
.schedule(() -> scheduledTask(),
(TriggerContext triggerContext) -> {
CronTrigger trigger = new CronTrigger(
expression,
TimeZone.getTimeZone(ZoneOffset.UTC));
return trigger.nextExecutionTime(triggerContext);
}));
}
@SchedulerLock(name = "TaskScheduler",
lockAtLeastFor = 20*1000, lockAtMostFor = 30*1000)
private void scheduledTask() {
System.out.println(
Thread.currentThread().getName() + " - " + Calendar
.getInstance()
.getTime();
}
@Bean(name = "threadPoolTaskScheduler")
public TaskScheduler getThreadPoolTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.setThreadNamePrefix("Scheduled-");
taskScheduler.setRejectedExecutionHandler(new
ThreadPoolExecutor.CallerRunsPolicy());
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.setAwaitTerminationSeconds(60);
taskScheduler.initialize();
return taskScheduler;
}
}
答案 0 :(得分:0)
我终于想出了一种完成查询的方法。与其使用@SchedulerLock批注,不如使用自定义的LockConfigurationExtractor将TaskScheduler包装到LockableTaskScheduler,并手动调度每个taskScheduler,如下所示:
DefaultLockManager defaultLockManager = new DefaultLockManager(lockProvider,
customizedLockConfigurationExtractor);
return new LockableTaskScheduler(taskScheduler, defaultLockManager);
答案 1 :(得分:0)
您可以创建一个 LockableTaskScheduler 对象并将其设置为 ScheduledTaskRegistrar。这将在每次执行之前检查 shedlock 表。
public LockableTaskScheduler getScheduler() {
LockConfigurationExtractor lockConfigurationExtractor = (task) -> Optional.
of(new LockConfiguration(Instant.now(), "schedulerJob", Duration.ofMinutes(15), Duration.ofMinutes(5)));
LockManager lockManager = new DefaultLockManager(lockProvider, lockConfigurationExtractor);
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("MyThreadPoolTaskScheduler");
scheduler.initialize();
return new LockableTaskScheduler(scheduler, lockManager);
}