2

我正在使用带有 shedlock 的 spring boot 来确保我的计划任务只能同时在一个实例中运行。

这是我的配置

@Configuration
@EnableScheduling
@EnableSchedulerLock(mode = 
EnableSchedulerLock.InterceptMode.PROXY_METHOD, 
defaultLockAtMostFor = "PT15M", 
defaultLockAtLeastFor = "PT2M")
public class SchedulerConfig implements SchedulingConfigurer {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(dataSource);
}
}

这是我的任务

@Scheduled(fixedDelayString = "2000")
@SchedulerLock(name = "ms.demo.scheduleTaskJob1")
public void scheduleTaskJob1() {
    logger.info("Fixed delay task called every 2 seconds after latest finished Execution Time - {}",dateTimeFormatter.format(LocalDateTime.now()));
}

这是 shedlock 表 NAME LOCK_UNTIL LOCKED_AT LOCKED_BY

这里的问题是,当我的任务在 03-JUL-19 06.37.55.858685000 PM 第一次运行时

Shedlock 将向 DB 中添加 1 行,如下所示:

ms.demo.scheduleTaskJob1    03-JUL-19 06.52.37.178573000 PM 03-JUL-19 06.37.55.858685000 PM MB0001

因为 defaultLockAtMostFor 是 15 分钟

任务完成后,会更新这条记录解锁,现在的行是:

ms.demo.scheduleTaskJob1    03-JUL-19 06.39.37.178573000 PM 03-JUL-19 06.37.55.858685000 PM MB0001

因为 defaultLockAtLeastFor 是 2 分钟。

当到下一次运行任务(2019-07-03T18:37:58.434650900Z)时,它将通过sql命令更新记录以获取锁定

update shedlock set LOCK_UNTIL = '', lock_at = '' , locked_by = 'MB0001' where name = 'MB0001' and LOCK_UNTIL <= '2019-07-03T18:37:58.434650900Z';

无法更新,因此任务不会运行。

在这里,我必须等待大约 2 分钟,直到当前时间结束 LOCK_UNTIL (03-JUL-19 06.39.37.178573000 PM),而我的任务配置了 2 秒延迟所以我的任务不会按预期每 2 秒运行一次,而是它将运行每 2 分钟。

4

3 回答 3

1

这是预期的行为。lockAtLeastFor 是设置运行之间最小间隔的参数。这意味着您不能比指定值更频繁地运行作业。它有助于解决节点之间的时间同步问题。

在您的特定情况下,当作业完成时,锁定会一直保持到指定的 2 分钟间隔到期(defaultLockAtLeastFor = "PT2M")。虽然这次 Spring 试图再次运行作业(因为作业间隔小于锁定间隔)并且 Shedlock 看到该作业被锁定并阻止新的运行。来源:https ://github.com/lukas-krecan/ShedLock (“注释您的计划任务”部分)。

要解决此问题,您需要将参数 defaultLockAtLeastFor 更改为小于或等于 2 秒的值,因为您在fixedDelayString = "2000"("PT2S")中指定了此值

于 2020-09-12T12:25:34.617 回答
0

您可以尝试在@EnableSchedulerLock注释@SchedulerLock(name = "ms.demo.scheduleTaskJob1", lockAtLeastFor = "PT2S")中使用非默认选项或更改defaultLockAtLeastFor

于 2020-12-07T15:43:29.817 回答
0

确保在 spring 2.x 之后使用 @EnableSchedulerLock。

于 2021-03-09T09:52:23.937 回答