IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 锁-spring shedlock -> 正文阅读

[Java知识库]锁-spring shedlock

背景

spring shedlock用于在分布式服务的情况下执行定时任务,例如定时删除数据库中的一些数据,做数据迁移等等操作。这项技术在项目的分布式服务中大量使用。
使用的主要原因有以下几点:

  • 定时任务的业务需要,要在服务service正常运行的过程当中同时在背后执行一些操作,满足我们的业务需要,定时任务也就是schedule task必不可少。
  • 分布式服务的要求。试想下面一个场景: 随着业务增长,有一天单个服务service的压力过大,一个服务支撑不住了,我们要考虑部署多个服务来分散压力。这时问题就来了,之前的定时任务,在各个服务上全都会跑,做着同样的事情,并且还会造成一些并发问题。这必然不是我们想要的结果,这时我们就会发现,虽然有多个服务,但是我们只能让这样的定时任务执行一次. 这时就可以考虑通过数据库来控制任务。因为多个服务的数据库依然是同一个。

用法配置

以postgres为例,我们可以按如下方式使用shedlock

首先我们需要引入对应的依赖:

  <!-- shed lock -->
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>${schedlock.version}</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>${schedlock.version}</version>
        </dependency>

然后我们需要创建一张shedlock需要用来存储scheduler lock信息的table

CREATE TABLE shedlock (
  name VARCHAR(64),
  lock_until TIMESTAMP(3) NULL,
  locked_at TIMESTAMP(3) NULL,
  locked_by VARCHAR(255),
  PRIMARY KEY (name)
)

通常,我们以锁的名字作为表的主键即可.
然后我们需要配置LockProvider, 使得访问数据库的时候使用shedlock

@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "30s")
public class SchedulerConfiguration {

    @Bean
    public LockProvider lockProvider(final DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }
}

有了以上配置之后我们就可以创建task了.

创建tasks

要创建一个由shedlock控制的schedule task,我们可以将@Scheduled和@SchedulerLock?注解放在对应的方法上即可.

@Component
public class SchedulerTaskTrigger {

    @Scheduled(fixedDelayString = "PT30S")
    @SchedulerLock(name = "TaskScheduler_scheduledTask", 
      lockAtLeastForString = "30s",
      lockAtMostForString = "3h")
    public void scheduledTask() {
        // ...
    }
}

然后,task里面的逻辑就会按照我们的配置所执行,上面的配置当中,最短lock时间设置为了30s,最长设置为了3小时,也就是说每一次task执行,这个task最少也会lock 30秒,而最长会lock3个小时,取决于实际执行任务的情况。

并且,在分布式多服务同时运行的情况下,同一时间也只会有一个服务执行task任务。

若每次执行任务都花了30s,那么我们就会在数据库里的表里看到下面的现象:

下一次执行:

可以看到每次从lockedat到lock until之间的时间都是30s,而上一次的lock until则会成为下一次的lock at时间。
如果查看task所执行的sql的话,我们会发现每次job执行,shedlock都会执行下面的两条sql:

//task started
UPDATE shedlock SET lock_until = ?, locked_at = ?, locked_by = ? WHERE name = ? AND lock_until <= ?;

//task execution
...

//task end
UPDATE shedlock SET lock_until = ? WHERE name = ?;

从本质上来说,shedlock解决分布式服务定时任务的做法,是借助了多个服务是基于同一数据库这一点。也就是说虽然是分布式的多个服务,但是他们依然依赖了同样的资源,即数据库。其他的一些解决方案,例如使用zookeeper或者使用redis的解决原理其实本质是一模一样的。 这个问题本质上也就是一个分布式锁的问题。解决办法自然就是寻找分布式服务共享的资源

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:49:43  更:2022-03-31 23:52:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:07:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码