Spring Cloud分布式定时器之ShedLock的实现

yizhihongxing

下面我来详细讲解一下“Spring Cloud分布式定时器之ShedLock的实现”的完整攻略。

一、ShedLock是什么

ShedLock是一个分布式定时任务解决方案,用于解决多个节点执行同一个任务的问题。它通过数据库上的行级锁来保证同一时间只有一个节点执行任务,其他的节点则会等待锁的释放。

二、ShedLock的实现

ShedLock的实现分为两个部分:锁的获取和锁的释放。

2.1 锁的获取

ShedLock的锁是通过数据库中的行级锁来实现的。它需要一个数据库来保存任务信息和锁信息。首先我们需要添加ShedLock的依赖:

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

然后我们需要配置ShedLock的数据源:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/lock?useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456

此外,我们还需要创建一个任务的Bean,并使用@Scheduled注解来定时执行任务。例如:

@Service
public class TaskService {
    @Autowired
    private LockProvider lockProvider;

    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "TaskService", lockAtLeastFor = "PT5S", lockAtMostFor = "PT6S")
    public void task() throws InterruptedException {
        Lock lock = lockProvider.lock("TaskService");
        if (lock != null) {
            System.out.println("任务开始执行");
            Thread.sleep(2000);
            System.out.println("任务执行完成");
            lock.unlock();
        } else {
            System.out.println("任务正在执行");
        }
    }
}

在该代码中,@Scheduled注解指定了任务的执行频率,@SchedulerLock注解指定了任务的名称以及锁的最小和最大锁定时间。在任务执行过程中,我们通过lockProvider.lock("TaskService")方法获取锁,如果获取成功,则执行任务,否则等待其他节点执行完成后再执行任务。

2.2 锁的释放

我们需要在任务执行完成后,及时地释放锁。ShedLock为我们提供了@SchedulerLock注解来自动释放锁,但是需要配合@EnableSchedulerLock注解来使用。例如:

@SpringBootApplication
@EnableSchedulerLock(defaultLockAtMostFor = "1m")
public class ShedLockApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShedLockApplication.class, args);
    }
}

在该代码中,@EnableSchedulerLock注解激活了@SchedulerLock注解的功能,我们可以在其中指定全局默认的最大锁定时间。

三、完整示例

下面是一个完整的示例:

@SpringBootApplication
@EnableSchedulerLock(defaultLockAtMostFor = "1m")
public class ShedLockApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShedLockApplication.class, args);
    }
}

@Service
public class TaskService {
    @Autowired
    private LockProvider lockProvider;

    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "TaskService", lockAtLeastFor = "PT5S", lockAtMostFor = "PT6S")
    public void task() throws InterruptedException {
        Lock lock = lockProvider.lock("TaskService");
        if (lock != null) {
            System.out.println("任务开始执行");
            Thread.sleep(2000);
            System.out.println("任务执行完成");
            lock.unlock();
        } else {
            System.out.println("任务正在执行");
        }
    }
}

在该示例中,我们定时地执行任务并使用ShedLock来保证任务只有一个节点执行。我们观察到,当一个节点在执行任务时,另一个节点会等待锁的释放。

四、示例说明

下面是两条示例说明:

4.1 多节点部署

假设我们有一个定时任务,需要每天凌晨进行数据更新。为了保证任务顺利执行,我们在多台服务器上部署同一个任务。

在这种情况下,如果我们不使用ShedLock,可能会造成数据重复更新或者数据遗漏的问题。因为在同一时刻,多个节点都有可能更新数据。

如果使用ShedLock来控制任务的执行,则可以保证同一时刻只有一个节点执行任务,避免数据更新的问题。这样,我们就可以在多个节点上部署同一个任务,而不必担心执行过程中出现问题。

4.2 多线程任务

假设我们有一个定时任务,需要每5秒钟执行一次。我们希望在每次执行任务时,执行一次其他操作。为了保证操作的正确性,我们需要在任务执行期间对该操作进行锁定。

在这种情况下,如果我们不使用ShedLock,则无法保证在每次任务执行时都对操作进行锁定。因为在多线程环境下,可能存在时间上的重叠。

使用ShedLock来控制任务的执行,则可以保证在每次任务执行时都对操作进行锁定。这样我们就可以在多线程环境下安全地使用分布式定时器了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Cloud分布式定时器之ShedLock的实现 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • Linux安装MySQL教程(二进制分发版)

    下面我详细讲解“Linux安装MySQL教程(二进制分发版)”的完整攻略。 1. 背景介绍 在Linux系统下进行MySQL的安装,有两种常见的方式:二进制分发版和源码编译版。本篇教程介绍的是MySQL的二进制分发版安装教程,适用于CentOS、RedHat等Linux系统。 2. 环境准备 在进行MySQL安装前,请确保你的Linux系统满足以下要求: 已…

    database 2023年5月22日
    00
  • Redis可视化工具Redis Desktop Manager的具体使用

    Redis Desktop Manager是一款开源的Redis可视化工具,支持Windows、MacOS、Linux等多个平台,可方便地管理Redis服务器和数据。以下是Redis Desktop Manager的具体使用攻略: 安装Redis Desktop Manager 首先,需要下载并安装Redis Desktop Manager,可以从其官网(h…

    database 2023年5月22日
    00
  • 在数据库里将毫秒转换成date格式的方法

    将毫秒数转换成date格式是非常常见的操作,可以使用数据库里的函数进行转换。下面是将毫秒数转换成date格式的详细攻略: 1.将毫秒数转换成date格式的函数 在数据库里,可以使用内置函数FROM_UNIXTIME()将时间戳转换成日期格式,然后将毫秒数除以1000转换成秒数作为参数传入该函数中即可。把函数的输出结果指定为日期格式即可输出日期。 以下是 My…

    database 2023年5月22日
    00
  • Linux 安装二进制MySQL 及 破解MySQL密码的方法

    安装二进制MySQL 及 破解MySQL密码的方法 下载MySQL二进制安装包 首先,需要从MySQL官方网站下载MySQL二进制安装包,下载地址为: https://dev.mysql.com/downloads/mysql/ 选择所需的操作系统和版本后进行下载。 安装MySQL 在Linux系统上,可以使用以下命令进行MySQL的安装: tar xvf …

    database 2023年5月22日
    00
  • ECSHOP在PHP5.5及高版本上报错的解决方法

    下面我将为您详细讲解“ECSHOP在PHP5.5及高版本上报错的解决方法”的完整攻略。 问题描述 在PHP5.5及其高版本中,如果使用ECShop(版本2.x)进行开发或者二次开发,那么可能会出现以下报错信息: Deprecated: Assigning the return value of new by reference is deprecated i…

    database 2023年5月18日
    00
  • Mysql 5.7 新特性之 json 类型的增删改查操作和用法

    Mysql 5.7 新特性之 json 类型的增删改查操作和用法 什么是json类型 JSON是JavaScript Object Notation的缩写,是一种用于数据交换的轻量级文本格式。MySQL 5.7支持JSON类型,可以在表的列中存储JSON格式的数据,这些数据可以在MySQL中进行查询和修改,支持JSON文档中的各种数据类型如字符串、数字、数组…

    database 2023年5月21日
    00
  • DBMS中2NF和3NF的区别

    当我们设计一个关系型数据库的时候,需要将数据进行归一化,以避免数据的冗余和不一致性。常见的归一化形式包括第一范式(1NF)、第二范式(2NF)和第三范式(3NF)等。这里,我将详细讲解DBMS中2NF和3NF的区别以及实例说明。 1. 什么是2NF和3NF? 2NF和3NF都是关系型数据库设计中的一种范式。具体来说,2NF和3NF通常是针对关系中的属性之间的…

    database 2023年3月27日
    00
  • spring整合atomikos实现分布式事务的方法示例

    下面我将为您详细讲解“spring整合atomikos实现分布式事务的方法示例”的完整攻略。 前置条件 要实现这一功能,需要先满足以下条件:- 已经安装了Atomikos事务管理器;- 项目已经使用Spring框架搭建。 步骤一:修改配置文件 在Spring配置文件中添加如下配置: <!– JTA 事务管理器 –> <bean id=&…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部