news 2026/7/2 4:15:09

如何用 ShedLock 让 Spring Boot 的定时任务在多实例环境下只执行一次

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何用 ShedLock 让 Spring Boot 的定时任务在多实例环境下只执行一次

执行。

原因很简单:默认情况下,Spring 不会在多个实例之间做调度同步。

这篇文章就聊聊怎么用 ShedLock,让定时任务在多实例环境下“同一时刻只跑一次”。顺便一提,它也能作为 Quartz 的替代。

Maven 依赖

先引入 shedlock-spring 这个依赖:

<dependency>

<groupId>net.javacrumbs.shedlock</groupId>

<artifactId>shedlock-spring</artifactId>

<version>6.3.1</version>

</dependency>

最新版本可以去 Maven Central 看。

配置

ShedLock 依赖“共享数据库”,并且要声明一个合适的 LockProvider。它会在库里新建一张表/文档,记录当前的锁。

目前它支持 Mongo、Couchbase、Elasticsearch、Redis、Hazelcast、ZooKeeper、Cassandra,以及任何带 JDBC 驱动的数据库。

示例我们用内存型 H2 数据库,方便演示。

要跑起来,先把 H2 和 JDBC 版的 ShedLock 依赖加上:

<dependency>

<groupId>net.javacrumbs.shedlock</groupId>

<artifactId>shedlock-provider-jdbc-template</artifactId>

<version>6.3.1</version>

</dependency>

<dependency>

<groupId>com.h2database</groupId>

<artifactId>h2</artifactId>

<version>2.1.214</version>

</dependency>

然后建一张表,专门存锁:

CREATE TABLE shedlock (

name VARCHAR(64),

lock_until TIMESTAMP(3) NULL,

locked_at TIMESTAMP(3) NULL,

locked_by VARCHAR(255),

PRIMARY KEY (name)

)

在 Spring Boot 里把数据源写到配置里,这样 DataSource 才能被注入。这里用 application.yml:

spring:

datasource:

driverClassName: org.h2.Driver

url: jdbc:h2:mem:shedlock_DB;INIT=CREATE SCHEMA IF NOT EXISTS shedlock;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

username: sa

password:

接着用这个数据源配置下 LockProvider,写法很直观:

@Configuration

public class SchedulerConfiguration {

@Bean

public LockProvider lockProvider(DataSource dataSource) {

return new JdbcTemplateLockProvider(dataSource);

}

}

别忘了再加上两个注解:@EnableScheduling 和 @EnableSchedulerLock:

@SpringBootApplication

@EnableScheduling

@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")

public class SpringBootShedlockApplication {

public static void main(String[] args) {

SpringApplication.run(SpringBootShedlockApplication.class, args);

}

}

defaultLockAtMostFor 表示执行节点挂了时,锁最多保留多久。格式用的是 ISO8601 持续时间。

下面的示例会演示怎么在方法上覆盖它。

创建任务

让 ShedLock 接管一个定时任务很简单:方法上同时加 @Scheduled 和 @SchedulerLock:

@Component

class BaeldungTaskScheduler {

@Scheduled(cron = "0 0/15 * * * ?")

@SchedulerLock(name = "TaskScheduler_scheduledTask",

lockAtLeastFor = "PT5M", lockAtMostFor = "PT14M")

public void scheduledTask() {

// ...

}

}

先说 @Scheduled:它支持 cron 表达式,上面的表达式表示“每 15 分钟执行一次”。

再说 @SchedulerLock:name 要唯一,一般用 类名_方法名 就够了。我们不希望同一个方法被同时运行,ShedLock 就是靠这个唯一名称来实现的。

我们还加了两个可选参数:

lockAtLeastFor 用来保证最少持锁时间,让两次执行之间留出一定间隔。使用 “PT5M” 表示至少 5 分钟。换句话说,这个方法被 ShedLock 控制后,运行频率不会高于每 5 分钟一次。

lockAtMostFor 用来指定在执行节点异常(比如宕机)时,锁最多会被保留多久。使用 “PT14M” 表示最多 14 分钟。

正常情况下任务结束会立即释放锁。其实在 @EnableSchedulerLock 里已经有默认值,这里只是展示如何在方法级别做覆盖。

总结

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 22:48:59

Digimat + Abaqus:编织复合材料分析的奇妙之旅

Digimat&#xff0b;abaqus编织复合材料分析 Digimat编织复合材料建模&#xff0c;网格划分&#xff0c;周期性边界条件 abaqus编织复合材料仿真分析在材料科学与工程领域&#xff0c;编织复合材料因其独特的性能备受关注。而借助 Digimat 和 Abaqus 这两款强大的工具&#xff…

作者头像 李华
网站建设 2026/7/2 22:36:28

臭双非的技术学习之旅——光线步进体积光篇

基于光线步进的体积光 2025年4月16日12:59:42 体积光是在体积云的基础上完成的。 首先我们要解决一个问题&#xff0c;我的光的颜色是怎么出来的&#xff1f; 回顾一下体积云&#xff0c;体积云的颜色&#xff0c;是射线上的float叠加出来的&#xff0c;那么体积光也是这样&…

作者头像 李华
网站建设 2026/7/2 19:24:17

利用 RPA 实现企业微信外部群的定时群发功能

利用 RPA&#xff08;机器人流程自动化&#xff09;实现企业微信外部群的定时群发功能&#xff0c;是一种有效的技术手段&#xff0c;它能突破官方 API 在主动消息推送方面的限制&#xff0c;确保您的运营内容在预定时间准确触达目标群组。 这个功能的实现主要依赖于两个核心组…

作者头像 李华
网站建设 2026/7/1 11:07:46

基于COMSOL的变压器流固耦合与振动噪声分析探索

基于COMSOL多物理场耦合仿真的变压器流固耦合及振动噪声分析 变压器流固耦合仿真&#xff0c;变压器振动噪声耦合仿真&#xff0c;提供能够有效运行的几何构造划分及仿真在电力系统中&#xff0c;变压器的性能至关重要&#xff0c;而流固耦合以及振动噪声问题直接影响着其运行的…

作者头像 李华