• 用shedlock实现分布式定时任务锁


    spring的定时任务经常被各个服务用到,比如定时清理日志,定时提醒,

    比较方便的就是用Scheduled注解了

    简单的配置一下就能用了

    @EnableScheduling
    @SpringBootApplication
    public class ScheduledLockApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ScheduledLockApplication.class, args);
        }
    
    }
    

      

    这里每2秒打印一下当前时间

    @Component
    public class ScheduledLock
    {
        @Scheduled(cron = "0/2 * * * * ?")
        public void run()
        {
            System.out.print(new Date().toString() + "
    ");
        }
    }
    

      

    但是!

    有一天服务的压力过大,一个服务支撑不住了,我们要考虑部署多个服务来分散压力

    这时问题就来了

    你突然发现你的定时系统,在各个服务上全她丫的跑起来了,做着同样的事情,这必然不是我们想要的结果

    这时你一定会想办法,让定时只执行一次

    比如一个服务一个配置文件,在配置文件中控制定时的开关

    再比如通过数据库的读写来控制定时的开关

    详尽任何办法,其实这些都是一些不错的解决办法

    但是!

    有一个更方便的东西

    那就是shedlock

    就叫她分布式定时任务锁吧

    她的锁分好多种

    Mongo,Redis,Hazelcast,ZooKeeper,还有所有带JDBC的东西

    这玩意用起来也特简单

    她的包

    <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-spring</artifactId>
        <version>2.2.0</version>
    </dependency>
    

      

    这里用JDBC的锁

    再添加一个包

    <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-provider-jdbc-template</artifactId>
        <version>2.2.0</version>
    </dependency>
    

    对她进行一下配置,创建一个她要用的bean

    @Configuration
    public class ScheduledLockConfig
    {
        @Bean
        public LockProvider lockProvider(DataSource dataSource) {
            return new JdbcTemplateLockProvider(dataSource);
        }
    }
    

      

    我用的mysql数据库

    在数据库中添加一张名为shedlock表

    这张表也是她要用的,她通过修改数据库表中的数据实现锁

    里面有四个字段

    主键name:每个定时任务的一个名字

    locked_at:锁的开始时间

    lock_until:锁的结束时间

    再定时开始时,会更新这两个时间,在时间之内的定时是不会被执行的

    在启动类上加上注解EnableSchedulerLock,开启定时任务锁,指定一个默认的锁的时间

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

      

    在栗子中添加注解SchedulerLock

    @Component
    public class ScheduledLock
    {
        private static final int lockTime = 1000;
    
        @Scheduled(cron = "0/2 * * * * ?")
        @SchedulerLock(name = "TaskScheduler_scheduledTask", lockAtMostFor = lockTime, lockAtLeastFor = lockTime)
        public void run()
        {
            System.out.print(new Date().toString() + "
    ");
        }
    }
    

      

    这个注解有五个参数

    name:定时任务的名字,就是数据库中的内个主键
    lockAtMostFor:锁的最大时间单位为毫秒
    lockAtMostForString:最大时间的字符串形式,例如:PT30S 代表30秒
    lockAtLeastFor:锁的最小时间单位为毫秒
    lockAtLeastForString:最小时间的字符串形式

    好了,起两个项目让她跑起来,看看结果

    虽然不是很规律,但是没有重复的时间

  • 相关阅读:
    Linux命令之 文件归档管理
    C#总结项目《影院售票系统》编写总结完结篇
    C#总结项目《影院售票系统》编写总结三
    C#中MD5加密
    C#中的序列化与反序列化
    C#总结项目《影院售票系统》编写总结二
    C#总结项目《影院售票系统》编写总结一
    java多线程与线程并发四:线程范围内的共享数据
    java多线程与线程并发三:线程同步通信
    java多线程与线程并发二:线程互斥
  • 原文地址:https://www.cnblogs.com/gutousu/p/10235160.html
Copyright © 2020-2023  润新知