首页 > 其他分享 >SpringBoot定时任务:使用shedlock解决SpringBoot分布式定时任务

SpringBoot定时任务:使用shedlock解决SpringBoot分布式定时任务

时间:2024-03-01 11:35:22浏览次数:27  
标签:net SpringBoot 任务 shedlock import 定时 节点

第一步:引入shedlock包
maven中pom文件添加如下配置:

<dependency>
   <groupId>net.javacrumbs.shedlock</groupId>
   <artifactId>shedlock-spring</artifactId>
   <version>4.33.0</version>   使用其他版本
</dependency>

第二步:添加shedlock-provider-jdbc-template依赖(以JDBC为例)
maven中pom文件添加如下配置:

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

若使用的是其他类型的数据库,需要添加的依赖也不同,以MongoDB为例:MongoDB的依赖如下:

<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-mongo</artifactId>
<version>4.14.0</version>
</dependency>

第三步:向数据库中插入表shedlock(必须)
建表语句如下:

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

第四步:添加配置类

package com.grg.tg.erp.config;

/**
* 加载定时任务库表
* @author ZJQ
* @date 2022/6/9
*/
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.sql.DataSource;

@EnableScheduling
@Configuration(proxyBeanMethods = false)
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class ShedlockAutoConfiguration {
private static final String TABLE_NAME = "spring_scheduler_shedlock";

@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withJdbcTemplate(new JdbcTemplate(dataSource))
.withTableName(TABLE_NAME)
.usingDbTime()
.build()
);
}
}

第五步:添加@SchedulerLock到定时器业务方法入口

@SchedulerLock(name = "scheduledTask", lockAtMostFor = ?, lockAtLeastFor = ?)


name属性:锁名称,必须指定,每次只能执行一个具有相同名字的任务,锁名称应该是全局唯一的;
lockAtMostFor属性:设置锁的最大持有时间,为了解决如果持有锁的节点挂了,无法释放锁,其他节点无法进行下一次任务;
lockAtMostForString属性:成功执行任务的节点所能拥有的独占锁的最长时间的字符串表达,例如“PT14M”表示为14分钟
lockAtLeastFor属性:指定保留锁的最短时间。主要目的是在任务非常短的且节点之间存在时钟差异的情况下防止多个节点执行。这个属性是锁的持有时间。设置了多少就一定会持有多长时间,再此期间,下一次任务执行时,其他节点包括它本身是不会执行任务的
lockAtLeastForString属性:成功执行任务的节点所能拥有的独占锁的最短时间的字符串表达,例如“PT14M”表示为14分钟

第六步:测试
本次遇到的问题是使用Scheduled定时发送邮件,在分布式系统中会根据节点数使每个节点发送重复的邮件,这样明显不符合业务要求。本次测试的定时任务代码如下:

//每天23:59:59 执行 将每天库存记录保存
@Scheduled(cron = "59 59 23 * * ? ")
@SchedulerLock(name = "spring_sssschedulr_shedlocks")
public void SaticScheduleTask() {
try{
List<ImmeditStockVo> calculateInventory = stockHouseService.getCalculateInventory();//获取当日操作库存记录及库存
List<DailyInventoryDTO> list = new ArrayList<>();
calculateInventory.forEach(e -> {
list.add(new DailyInventoryDTO()
.setPartsId(e.getPartsId())
.setStoreId(e.getStoreId())
.setWhouseId(e.getWhouseId())
.setInventoryQuantityDay(e.getSamedayStockNumber())
.setStatisticalDate(e.getSamedayInventoryTime()));
});
stockHouseService.saveDailyInventory(list); //统计每天最终库存
logger.info("执行当日库存记录定时任务"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}catch (Exception e){
logger.error("执行当日库存记录定时任务异常"+e);
e.printStackTrace();
}
}

 

标签:net,SpringBoot,任务,shedlock,import,定时,节点
From: https://www.cnblogs.com/pijunqi/p/18046600

相关文章

  • springboot应用中根据特定条件使用CommandLineRunner
    PS使用SpringBoot3.1.2进行测试1.使用@ConditionalOnProperty仅当特定属性存在或具有特定值时,注释@ConditionalOnProperty才会创建bean。在此示例中,仅当或文件中的CommandLineRunner属性db.init.enabled设置为true时才会执行application.propertiesapplication.ymlpac......
  • 一键搞定定时自动化通知
    一键搞定定时自动化通知您是否经常忘了需要每周要填报工作时长?您的团队是否需要每月定时盘点HC?您是否每月末都在工作群提醒大家更新OKR?这些简单的定时任务是不是经常会忘记或者占用您的精力?如果你也有这些烦恼,是时候来试试这个应用与数据集成平台——阿里云计算巢AppFlow了,它能......
  • 定时提醒再也不用担心忘记啦
    定时提醒再也不用担心忘记啦~~~    好记性不如烂笔头,烂笔头不如靠谱的自动化~~~正在寻找自动化流程编排工具或定时任务工具的朋友们赶紧看过来,为你介绍一款简单配置即可实现自动化定时提醒的平台阿里云计算巢AppFLow。    利用它可以通过简单的几步配置实现自动化定时任务和各......
  • 定时任务
    配置接口packagetest;importjava.util.concurrent.TimeUnit;publicinterfaceIScheduledCfg{StringgetName();intgetCount();longgetInitialDelay();longgetCycleTime();TimeUnitgetTimeUnit();}配置类packagetest;importlom......
  • springboot将用户认证信息提取到上下文,获取用户实体
    @ServicepublicclassInfoServiceImplimplementsInfoService{@OverridepublicMap<String,String>getinfo(){//将用户认证信息从上下文中(SecurityContext)提取出来UsernamePasswordAuthenticationTokenauthenticationToken=......
  • SpringBoot
    SpringBoot特性快速创建独立Spring应用SSM:导包、写配置、启动运行直接嵌入Tomcat、JettyorUndertow(无需部署war包)【Servlet容器】linuxjavatomcatmysql:war放到tomcat的webapps下jar:java环境;java-jar重点:提供可选的starter,简化应用整合场景启动器(starter)......
  • springboot中实现一个接口
    实现一个接口,需要在service里写一个接口,写一个实现,在controller里写一个类chatgpt4.0:在Spring框架中,实现一个接口通常遵循一种分层的架构模式,这种模式涉及到至少三个主要部分:接口定义、服务层实现、以及控制器层。这个流程确保了应用程序的高内聚、低耦合特性,同时也符合Spring......
  • c# 4.8 实现Windows 定时任务计划(Task Scheduler)
    分享一个我自己写的 Windows定时任务计划(TaskScheduler)动态创建代码,没做太多封装,留个实现笔记首先封装一个简单配置项的类publicclassTaskSchedulerConfig{///<summary>///引用程序路径///</summary>publicstringApplicationPath{get;set;......
  • springboot 集成 Dataway
    1.Dataway简介Dataway是Hasor生态中的一员,它通过提供一个UI界面来帮助开发者完成接口配置、测试、冒烟和发布等一系列任务。用户可以在Dataway的界面中进行接口的配置,无需编写任何代码。Dataway底层基于DataQL服务聚合能力,通过DataQL语言实现接口的聚合和定义,从而消除了传统开发......
  • 关于druid与springboot版本问题
    datasource:druid:driver-class-name:${sky.datasource.driver-class-name}url:jdbc:mysql://${sky.datasource.host}:${sky.datasource.port}/${sky.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=u......