@SchedulerLock注解使用
创始人
2024-11-14 05:38:25
0

文章目录

  • @Scheduled注解
  • 参数介绍
  • 建表
  • 配置类
  • 示例
  • 参考

如果服务中使用了@Scheduled注解,且服务部署了多个节点。那么在同一时刻,所有节点都会执行定时任务。但有有些任务我们只需执行一次,这就需要使用分布式锁的方式来控制,如可以使用如基于Redis的Lock4J框架。

@Scheduled注解

本文介绍一个SchedulerLock,SchedulerLock分布式锁可以基于Mysq,Redis、Mongo等中间件,本文介绍基于Mysql的方式,为什么使用Mysql呢,因为Mysql是我们业务中基本上一定会使用的中间件,使用MySQL不使用Redis,可以减少一个中间件,哈哈。
在bulid文件引入依赖,建议引入较新版本

    api 'net.javacrumbs.shedlock:shedlock-spring:4.42.0'     api 'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:4.42.0' 

较新版本中的@SchedulerLock源码只有3个参数,比老版本的较少。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface SchedulerLock {     /**      * Lock name.      */     String name() default "";       /**      * How long the lock should be kept in case the machine which obtained the lock died before releasing it.      * This is just a fallback, under normal circumstances the lock is released as soon the tasks finishes.      *      * Can be either time with suffix like 10s or ISO8601 duration as described in {@link java.time.Duration#parse(CharSequence)}, for example PT30S.      */     String lockAtMostFor() default "";       /**      * The lock will be held at least for given duration. Can be used if you really need to execute the task      * at most once in given period of time. If the duration of the task is shorter than clock difference between nodes, the task can      * be theoretically executed more than once (one node after another). By setting this parameter, you can make sure that the      * lock will be kept at least for given period of time.      *      * Can be either time with suffix like 10s or ISO8601 duration as described in {@link java.time.Duration#parse(CharSequence)}, for example PT30S.      */     String lockAtLeastFor() default ""; } 

参数介绍

name任务唯一标识。最重要的参数。同一个name的任务,同一个时刻,多个线程只会有一个线程获取到锁。其他没有获取到锁的线程会跳过,不会阻塞等待
在这里插入图片描述

lockAtLeastFor持有锁的最短时间。这个主要是防止不同节点时间存在误差,比如有个任务是0点执行,节点1的时间是准的,在0点执行花了30秒执行完成。节点2的时间比节点1慢了1分钟,那么节点2到0点的时候,又执行了一次任务。这个参数可以设置10秒、30秒等。保证不同节点的时间戳不会出现。
lockAtMostFor持有锁的最长时间。主要是为了防止死锁。当一个任务执行完成时会释放锁,当一个任务执行超过lockAtMostFor时间时,也会释放锁。这个时间要大于业务执行的时间,不然一个任务可能会被执行多次。

建表

我这里是使用的MySQL方式,所以需要建表。

CREATE TABLE `shedlock` (     `name`       varchar(64) COLLATE utf8_bin  NOT NULL,     `lock_until` timestamp(3)                  NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP (3),     `locked_at`  timestamp(3)                  NOT NULL DEFAULT CURRENT_TIMESTAMP(3),     `locked_by`  varchar(255) COLLATE utf8_bin NOT NULL,     PRIMARY KEY (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;  

主键一定要是name!

配置类

注入MySQL数据源

@Configuration @EnableSchedulerLock(defaultLockAtMostFor = "PT180S") public class ShedlockConfig {     @Autowired     private DataSource dataSource;     @Bean     public LockProvider lockProvider() {         return new JdbcTemplateLockProvider(                 JdbcTemplateLockProvider.Configuration.builder()                         .withJdbcTemplate(new JdbcTemplate(dataSource))                         .build()         );     } } 

@EnableSchedulerLock注解不要忘记开启~

示例

    @Scheduled(cron = "0 0/1 * * * ?")     @SchedulerLock(name = "myTask1", lockAtLeastFor = "PT30S", lockAtMostFor = "PT20M")     public void myTask1() {         log.info("mytask start. thread:{} time:{}", Thread.currentThread().getName(), new SimpleDateFormat("yyyy-MM-dd HH::mm:ss").format(new Date()));         long start = System.currentTimeMillis();         try {             myService.process();         } catch (Exception e) {             log.error("mytask error.", e);         }         log.info("pmytask. use time:{} s", (System.currentTimeMillis() - start) / 1000);     } 

执行完后MySQL表会自动生成几天记录,name就是任务名称~
在这里插入图片描述

参考

官方资料:https://github.com/lukas-krecan/ShedLock

相关内容

热门资讯

热点推荐!微信小程序途游辅助免... 热点推荐!微信小程序途游辅助免费,有哪些免费的wpk作弊码,细节揭秘(有挂技巧)-哔哩哔哩是一款可以...
重大消息!互游辅助脚本,哈糖大... 重大消息!互游辅助脚本,哈糖大菠萝怎么开挂,德州教程(有挂助手)-哔哩哔哩;互游辅助脚本简单的灵活控...
推荐一下!福建天天开心辅助真实... 推荐一下!福建天天开心辅助真实性,黑桃a3辅助,一贯有挂(哔哩哔哩)1、起透看视 福建天天开心辅助真...
今日焦点!腾讯欢乐卡五星辅助器... 今日焦点!腾讯欢乐卡五星辅助器,wepoker怎么下载游戏,力荐教程(真是有挂)-哔哩哔哩;亲,有的...
解谜一下!大宝苏北麻将怎么开挂... 解谜一下!大宝苏北麻将怎么开挂,开心游戏快跑辅助,其实存在有挂(哔哩哔哩)大宝苏北麻将怎么开挂能透视...
一分钟揭秘!边锋老友杰克辅助,... 一分钟揭秘!边锋老友杰克辅助,wepoker私人局俱乐部怎么进,插件教程(新版有挂)-哔哩哔哩;AI...
详情一下!九九山城辅助免费,浙... 详情一下!九九山城辅助免费,浙江宝宝游戏辅助工具,一贯存在有挂(哔哩哔哩)1、下载好九九山城辅助免费...
玩家必看教程!白金岛跑胡子脚本... 玩家必看教程!白金岛跑胡子脚本,微扑克游戏辅助器,科技教程(有挂秘诀)-哔哩哔哩;白金岛跑胡子脚本最...
有挂一下!老友广东潮汕麻雀,山... 有挂一下!老友广东潮汕麻雀,山西扣点带你辅助工具破解,都是是有挂(哔哩哔哩)1、老友广东潮汕麻雀模拟...
今日重大通报!花舍辅助,wep... 今日重大通报!花舍辅助,wepoker软件靠谱么,必备教程(有挂方式)-哔哩哔哩;1、不需要AI权限...