Spring 带 shedlock 的引导计划任务不是 运行 延迟
Spring boot schedule task with shedlock not running by its delay
我正在使用 spring boot with shedlock 以确保我的计划任务仅 运行 同时在一个实例中。
这是我的配置
@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 table
姓名
LOCK_UNTIL
LOCKED_AT
LOCKED_BY
这里的问题是,当我的任务 运行 第一次在 03-JUL-19 06.37.55.858685000 PM
Shedlock 将像这样向数据库添加 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),而我的任务配置为 2s 延迟
所以我的任务不是像预期的那样每 2 秒 运行,而是每 2 分钟 运行。
这是预期的行为。 lockAtLeastFor 是设置 运行s 之间的最小间隔的参数。这意味着您不能 运行 比指定值更频繁的作业。它有助于修复节点之间的时间同步问题。
在您的特定情况下,当作业完成时,锁定会一直保持,直到指定的 2 分钟间隔到期 (defaultLockAtLeastFor = "PT2M"
)。这次 Spring 再次尝试 运行 作业(因为作业间隔小于锁定间隔)并且 Shedlock 看到该作业被锁定并阻止新的 运行。资料来源:https://github.com/lukas-krecan/ShedLock(“注释您的计划任务”部分)。
要解决此问题,您需要将参数 defaultLockAtLeastFor 的值更改为小于或等于 2 秒,因为您在 fixedDelayString = "2000"
(“PT2S”)
中指定了此值
您可以尝试@SchedulerLock(name = "ms.demo.scheduleTaskJob1", lockAtLeastFor = "PT2S")
使用非默认选项或更改defaultLockAtLeastFor
,在@EnableSchedulerLock注释
确保在 spring 2.x 之后使用 @EnableSchedulerLock。
我正在使用 spring boot with shedlock 以确保我的计划任务仅 运行 同时在一个实例中。
这是我的配置
@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 table 姓名 LOCK_UNTIL LOCKED_AT LOCKED_BY
这里的问题是,当我的任务 运行 第一次在 03-JUL-19 06.37.55.858685000 PM
Shedlock 将像这样向数据库添加 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),而我的任务配置为 2s 延迟 所以我的任务不是像预期的那样每 2 秒 运行,而是每 2 分钟 运行。
这是预期的行为。 lockAtLeastFor 是设置 运行s 之间的最小间隔的参数。这意味着您不能 运行 比指定值更频繁的作业。它有助于修复节点之间的时间同步问题。
在您的特定情况下,当作业完成时,锁定会一直保持,直到指定的 2 分钟间隔到期 (defaultLockAtLeastFor = "PT2M"
)。这次 Spring 再次尝试 运行 作业(因为作业间隔小于锁定间隔)并且 Shedlock 看到该作业被锁定并阻止新的 运行。资料来源:https://github.com/lukas-krecan/ShedLock(“注释您的计划任务”部分)。
要解决此问题,您需要将参数 defaultLockAtLeastFor 的值更改为小于或等于 2 秒,因为您在 fixedDelayString = "2000"
(“PT2S”)
您可以尝试@SchedulerLock(name = "ms.demo.scheduleTaskJob1", lockAtLeastFor = "PT2S")
使用非默认选项或更改defaultLockAtLeastFor
,在@EnableSchedulerLock注释
确保在 spring 2.x 之后使用 @EnableSchedulerLock。