提示:net.javacrumbs.shedlock.core.LockProvider‘ available( SpringBoot微服务整合Scheduled 与 SchedulerLock问题)

业务需求:

项目部署要求做Nginx负载均衡、,多节点情况下,容易造成单个定时任务重复执行。于是需要对定时任务模块进行优化、保证定时任务执行的唯一性。

技术选择

因为定时任务也比较简单,执行频率固定,技术选择上就不对定时任务做自定义页面可配置了。直接上定时任务cron表达式执行。此处根据业务需求选择 Scheduled 与 SchedulerLock锁进行保证唯一性。

实现方式

话不多说,直接上代码:

  1. 引入依赖

pom文件中添加依赖:

<dependency>
	<groupId>net.javacrumbs.shedlock</groupId>
	<artifactId>shedlock-spring</artifactId>
	<version>3.0.1</version>
</dependency>
<dependency>
	<groupId>net.javacrumbs.shedlock</groupId>
	<artifactId>shedlock-provider-jdbc-template</artifactId>
	<version>3.0.1</version>
</dependency>
  1. 创建定时任务锁需要的表
-- 创建定时任务表
CREATE TABLE shedlock(
    name VARCHAR(64) ,
    lock_until TIMESTAMP(3) NULL,
    locked_at TIMESTAMP(3) NULL,
    locked_by  VARCHAR(255),
    PRIMARY KEY (name)
)
  1. 自定义设置分布式定时任务注册器以及数据库锁设置
package com.uniceu.admin.webservice.config;

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.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import javax.sql.DataSource;

/**
 * @author wangzibo
 * @date 2023年11月27日 8:43
 * @Description 分布式定时任务配置
 */
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class ScheduledLockConfig implements SchedulingConfigurer {

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

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(taskScheduler());
    }
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(64);
        return taskScheduler;
    }
}

注意此处引入的@EnableSchedulerLock 注解defaultLockAtMostFor属性 指定在执行节点结束时保留锁的默认时间、此处默认时间可根据需求来。后续业务定时任务模块会根据接口需要覆盖。

4. 定时任务实现
验证:
注意若想保住同一个定时任务只执行一次,需保证 @SchedulerLock(name = “fiveMLock”) 注解name属性是唯一的。多节点下需保证执行的业务接口name属性值一致即可!

package com.uniceu.admin.webservice.config;



import com.uniceu.core.utils.DateUtils;
import net.javacrumbs.shedlock.core.SchedulerLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wangzibo
 * @date 
 * @Description 
 */
@Component
public class DmI6000KpiJob{

    /**
     * 1分钟执行一次记录操作
     */
    @Scheduled(cron = "0 */1 * * * ?")
    @SchedulerLock(name = "fiveMLock",lockAtMostFor = 7 * 60 * 1000, lockAtLeastFor =1 * 60 * 1000)
    public void  fiveMJobI600Sys(){
 	        System.out.println("====================定时任务 一 抢到锁啦!!!!!");

}

    /**
     * 1分钟执行一次记录操作
     */
    @Scheduled(cron = "0 */1 * * * ?")
    @SchedulerLock(name = "fiveMLock",lockAtMostFor = 7 * 60 * 1000, lockAtLeastFor =1 * 60 * 1000)
    public void  fiveMJobs(){
 	        System.out.println("====================定时任务 二 抢到锁啦!!!!!");

}
}

lockAtMostFor = 7 * 60 * 1000, 属性:最多等待时长、单位毫秒
lockAtLeastFor =1 * 60 * 1000
属性:最少等待时长、单位毫秒

根据业务场景自定义。此处设置了会覆盖默认的时长。

常见问题

  1. 导包依赖导错,导包是 import net.javacrumbs.shedlock.core.SchedulerLock; 注意不要导错!
  2. 导包版本过高与springboot版本冲突
  3. 数据库用户权限不足,无法将当前执行的定时任务信息写入定时任务表。(定时任务表数据会自动写入和清除)
  4. 未添加@EnableScheduling
    @EnableSchedulerLock(defaultLockAtMostFor = “PT30S”)
    注解,导致不执行。
  5. @Component 该注解失效(在启动类上添加@ComponentScan(basePackages = { “定时任务类所在包”}))
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值