服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - SpringBoot 集成 ShedLock 分布式锁的示例详解

SpringBoot 集成 ShedLock 分布式锁的示例详解

2021-11-24 11:49weixin_35688430 Java教程

ShedLock是一个在分布式环境中使用的定时任务框架,用于解决在分布式环境中的多个实例的相同定时任务在同一时间点重复执行的问题,本文重点给大家介绍SpringBoot 分布式锁ShedLock的相关知识,感兴趣的朋友一起看看吧

一:ShedLock 简介

ShedLock是一个在分布式环境中使用的定时任务框架,用于解决在分布式环境中的多个实例的相同定时任务在同一时间点重复执行的问题。ShedLock确保计划的任务最多同时执行一次。如果一个任务正在一个节点上执行,它会获得一个锁,该锁将阻止从另一个节点(或线程)执行同一任务。请注意,如果一个任务已经在一个节点上执行,则在其他节点上的执行不会等待,只是将其跳过。。简单来说,ShedLock本身只做一件事情:保证一个任务最多同时执行一次。所以如官网所说的,ShedLock不是一个分布式调度器,只是一个锁!

注意:ShedLock支持Mongo,Redis,Hazelcast,ZooKeeper以及任何带有JDBC驱动程序的东西。本例子使用的是基于Redis的方式。之所以不适用基于jdbc存储的主要原因是考虑到大量数据下的数据库压力的原因,若本身基于jdbc等,可直接参考官网给出的提示:

创建对应的表结构。

?
1
2
3
4
5
6
7
CREATE TABLE shedlock(
    name VARCHAR(64),
    lock_until TIMESTAMP(3) NULL,
    locked_at TIMESTAMP(3) NULL,
    locked_by  VARCHAR(255),
    PRIMARY KEY (name)
)

二:配置maven 依赖

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-redis-spring</artifactId>
            <version>2.3.0</version>
        </dependency>
        
        <!--spring2.0集成redis所需common-pool2 -->
        <!-- 必须加上,jedis依赖此 若项目中已经引入jedis 请忽略此步骤-->
        <!-- spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/ -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

添加jedis 依赖 若项目中已经引入jedis 请忽略此步骤

?
1
2
3
4
5
6
<!--spring2.0集成redis所需common-pool2 -->
       <!-- 必须加上,jedis依赖此 若项目中已经引入jedis 请忽略此步骤-->
       <dependency>
           <groupId>org.apache.commons</groupId>
           <artifactId>commons-pool2</artifactId>
       </dependency>

三:SchedulerLock 基于 Redis 的配置

配置 lockProvider 并且开启 @EnableSchedulerLock 标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
 
/**
 * @Description SchedulerLock 基于 Redis 的配置
 * @Author
 * @Date 2020/2/22 18:27
 **/
@Configuration
//defaultLockAtMostFor 指定在执行节点结束时应保留锁的默认时间使用ISO8601 Duration格式
//作用就是在被加锁的节点挂了时,无法释放锁,造成其他节点无法进行下一任务
//这里默认55s
//关于ISO8601 Duration格式用的不到,具体可上网查询下相关资料,应该就是一套规范,规定一些时间表达方式
@EnableSchedulerLock(defaultLockAtMostFor = "PT55S")
public class ShedLockRedisConfig {
 
    @Value("${spring.profiles.active}")
    private String env;
 
    @Bean
    public LockProvider lockProvider(RedisConnectionFactory connectionFactory) {
        //环境变量 -需要区分不同环境避免冲突,如dev环境和test环境,两者都部署时,只有一个实例进行,此时会造成相关环境未启动情况
        return new RedisLockProvider(connectionFactory, env);
    }
}

四:在启动类中添加 @EnableScheduling 标签

注意,要在启动类上添加 @EnableScheduling ,表明开启定时器服务。若不加定时器是不会起效的。

?
1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableScheduling
public class EpidemicMessageApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(EpidemicMessageApplication.class, args);
    }
}

五:test 测试案例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//区分服务
    @Value("${server.port}")
    private String port;
    
    @Scheduled(cron = "0 */1 * * * ?")
    /**
     * lockAtLeastForString的作用是为了防止在任务开始之初由于各个服务器同名任务的服务器时间差,启动时间差等这些造成的一些问题,有了这个时间设置后,
     *     就可以避免因为上面这些小的时间差造成的一些意外,保证一个线程在抢到锁后,即便很快执行完,也不要立即释放,留下一个缓冲时间。
     *     这样等多个线程都启动后,由于任务已经被锁定,其他没有获得锁的任务也不会再去抢锁。注意这里的时间不要设置几秒几分钟,尽量大些
     *lockAtMostForString 这个设置的作用是为了防止抢到锁的那个线程,因为一些意外死掉了,而锁又始终不被释放。
     *     这样的话,虽然当前执行周期虽然失败了,但以后的执行周期如果这里一直不释放的话,后面就永远执行不到了。
     *     它的目的不在于隐藏任务,更重要的是,释放锁,并且查找解决问题。
     *至于是否带有string后缀,只是2种表达方式,数字类型的就是毫秒数,字符串类型的就有自己固定的格式 ,例如:PT30S  30s时间设置,单位可以是S,M,H
     */
    @SchedulerLock(name = "scheduledController_notice", lockAtLeastForString = "PT15M", lockAtMostForString = "PT14M")
    public StandardResult notice() {
        try {
            logger.info(port + "- 执行定时器 scheduledController_notice");
            return StandardResult.ok();
        } catch (Exception e) {
            logger.error("异常信息:", e);
            return StandardResult.faild("异常信息", e);
        }
    }

SchedulerLock注解说明
@SchedulerLock注解一共支持五个参数,分别是

name:用来标注一个定时服务的名字,被用于写入数据库作为区分不同服务的标识,如果有多个同名定时任务则同一时间点只有一个执行成功
lockAtMostFor:成功执行任务的节点所能拥有独占锁的最长时间,单位是毫秒ms
lockAtMostForString:成功执行任务的节点所能拥有的独占锁的最长时间的字符串表达,例如“PT14M”表示为14分钟,单位可以是S,M,H
lockAtLeastFor:成功执行任务的节点所能拥有独占所的最短时间,单位是毫秒ms
lockAtLeastForString:成功执行任务的节点所能拥有的独占锁的最短时间的字符串表达,例如“PT14M”表示为14分钟,单位可以是S,M,H

到此这篇关于SpringBoot 集成 ShedLock 分布式锁的文章就介绍到这了,更多相关SpringBoot 分布式锁ShedLock内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_35688430/article/details/119778849

延伸 · 阅读

精彩推荐
  • Java教程java SpringMVC学习使用详解

    java SpringMVC学习使用详解

    本篇文章主要介绍了java SpringMVC——如何获取请求参数详解,详细的介绍了每种参数注解的用法及其实例。感兴趣的小伙伴们可以参考一下...

    wbb1642020-09-12
  • Java教程Java中正则表达式的使用和详解(下)

    Java中正则表达式的使用和详解(下)

    这篇文章主要介绍了Java正则表达式的使用和详解(下)的相关资料,包括常用正则表达式和正则表达式语法,非常不错,具有参考借鉴价值,需要的的朋友参...

    落叶的博客2182020-09-20
  • Java教程java通过JFrame做一个登录系统的界面完整代码示例

    java通过JFrame做一个登录系统的界面完整代码示例

    这篇文章主要介绍了java通过JFrame做一个登录系统的界面完整代码示例,具有一定借鉴价值,需要的朋友可以参考下。...

    JIONGZONG9552021-03-09
  • Java教程MyEclipse到期破解代码分享

    MyEclipse到期破解代码分享

    前几天有个小伙伴咨询,使用的时候一直说myeclipse已过期,需要购买,如何解决?可以去网上搜搜注册码,但作为程序猿这么做简直太无趣,看看我们自己来...

    hebedich2912019-12-04
  • Java教程多模字符串匹配算法原理及Java实现代码

    多模字符串匹配算法原理及Java实现代码

    这篇文章主要介绍了多模字符串匹配算法原理及Java实现代码,涉及算法背景,原理,构建过程简单介绍几Java代码实现等相关内容,具有一定参考价值,需...

    hwYang4972021-02-14
  • Java教程Spring的注解配置与XML配置之间的比较

    Spring的注解配置与XML配置之间的比较

    在很多情况下,注释配置比 XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完...

    java之家4252019-10-14
  • Java教程Java Map 按照Value排序的实现方法

    Java Map 按照Value排序的实现方法

    Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。这篇文章主要介绍了Java Map 按照Value排序的实现方法,需要的朋友可以...

    crane-yuan4102020-06-04
  • Java教程深入解析Java编程中final关键字的作用

    深入解析Java编程中final关键字的作用

    final关键字正如其字面意思一样,意味着最后,比如被final修饰后类不能集成、变量不能被再赋值等,以下我们就来深入解析Java编程中final关键字的作用: ...

    Ider1762020-05-17