Scheduling配合nacos的yml实现动态定时任务

------------不带时区的自定义定时任务--------start--------

配置好nacos的yml动态配置,为前提

配置nacos的yml

test:
	schedule:
	   #服务器为0时区,因此设置每天下午16点执行,相当于东8区的晚上12点
	   crons: {"guideUserSchedule":"0/20 * * * * ?"}
	   # 默认是115
	   min: 20

编写调用器

package app.ljq.service.admin.config.scheduled;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 定时任务配置
 */
//@RefreshScope - 使用这个会创建两个任务-弃用
@Component
@EnableScheduling
@Slf4j
public class ScheduledConfig implements SchedulingConfigurer, ApplicationContextAware {

    private ApplicationContext applicationContext;
    @Autowired
    private Crons crons;

    /**
     * 添加定时任务
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        crons.getCrons().forEach((beanId, cron) -> {
            try {
                Runnable runnable = (Runnable) applicationContext.getBean(beanId);
                scheduledTaskRegistrar.addCronTask(runnable, cron);
            } catch (Exception e) {
                log.warn("实例化task失败[" + beanId + "]", e);
            }
        });
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Configuration
    @ConfigurationProperties(prefix = "test")
    @Data
    @RefreshScope
    public static class Crons {
        public Map<String, String> crons;

        private Integer min = 115;
    }
}

编写任务

package app.ljq.service.admin.job;

import app.ljq.lib.mq.config.MqDefineConstant;
import app.ljq.lib.mq.domain.OfflineMessageDTO;
import app.ljq.lib.mq.rabbit.RabbitRouter;
import app.ljq.lib.mq.rabbit.RabbitSender;
import app.ljq.service.admin.config.scheduled.ScheduledConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component("guideUserSchedule") //指定值,方便上下文获取任务
public class GuideUserSchedule implements Runnable {
    @Resource
    private ScheduledConfig.Crons crons;
    
    @Override
    public void run() {
        //定义要延迟多少分钟
        int min = crons.getMin();
        //头像时间
        long avatarTime = TimeUnit.MINUTES.toMillis(getRandomMin(min));
        log.debug("offlineMessage: 上传头像信息触发的时间:{}, 现在时间:{}", avatarTime, LocalDateTime.now());
        RabbitSender.convertAndDelaySend(RabbitRouter.builder()
                        .exchange(MqDefineConstant.Exchange.OFFLINE_MESSAGE_DELAY_EXCHANGE)
                        .routingKey(MqDefineConstant.RoutingKey.OFFLINE_MESSAGE_DELAY_KEY).build(),
                OfflineMessageDTO.builder().type(OfflineMessageDTO.OfflineMessageType.UPLOAD_AVATAR_MESSAGE.name()).build(),
                avatarTime
        );
        //促活时间
        long promoteTime = TimeUnit.MINUTES.toMillis(getRandomMin(min));
        log.debug("offlineMessage: 促活信息触发的时间:{}, 现在时间:{}", promoteTime, LocalDateTime.now());
        RabbitSender.convertAndDelaySend(RabbitRouter.builder()
                        .exchange(MqDefineConstant.Exchange.OFFLINE_MESSAGE_DELAY_EXCHANGE)
                        .routingKey(MqDefineConstant.RoutingKey.OFFLINE_MESSAGE_DELAY_KEY).build(),
                OfflineMessageDTO.builder().type(OfflineMessageDTO.OfflineMessageType.GUIDE_USER_MESSAGE.name()).build(),
                promoteTime
        );
    }

    /**
     * 得到随机分钟数
     *
     * @param min 最小值
     * @return int
     */
    public int getRandomMin(int min) {
        return (int) (Math.random() * min + 5);
    }

}

------------不带时区的自定义定时任务--------end--------

------------带时区的自定义定时任务--------start--------

nacos 的yml

static:
  schedule:
    crons:
      - {beanId: "countryDayStatsSchedule", cron: "0 0/5 * * * ?", ofHours: 8}

任务配置

package app.woya.service.statis.config.scheduled;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.time.ZoneOffset;
import java.util.List;
import java.util.TimeZone;

/**
 * 定时任务配置
 */
//@RefreshScope
@Component
@EnableScheduling
@Slf4j
public class ScheduledConfig implements SchedulingConfigurer, ApplicationContextAware {

    private ApplicationContext applicationContext;
    @Autowired
    private Crons crons;

    /**
     * 添加定时任务
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        crons.getCrons().forEach(baseCronsData -> {
            try {
                Runnable runnable = (Runnable) applicationContext.getBean(baseCronsData.getBeanId());
                scheduledTaskRegistrar.addCronTask(
                        new CronTask(runnable,
                                new CronTrigger(
                                        baseCronsData.getCron(),
                                        TimeZone.getTimeZone(ZoneOffset.ofHours(baseCronsData.getOfHours()))
                                )
                        )
                );
            } catch (Exception e) {
                log.warn("实例化task失败[" + baseCronsData.getBeanId() + "]", e);
            }
        });
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Configuration
    @ConfigurationProperties(prefix = "static.schedule")
    @Data
    @RefreshScope
    public static class Crons {
        public List<BaseCronsData> crons;
    }

    @NoArgsConstructor
    @Data
    public static class BaseCronsData {
        /**
         * runnable的类名
         */
        public String beanId;
        /**
         * cron
         */
        public String cron;
        /**
         * 时区
         */
        public Integer ofHours;
    }
}

任务

package app.ljq.service.statis.job;

import app.ljq.lib.redis.RedisKeyBaseBuilder;
import app.ljq.service.statis.service.user.ImCountryDayStatsService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneOffset;

@Component("countryDayStatsSchedule")
public class CountryDayStatsSchedule implements Runnable {

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private ImCountryDayStatsService imCountryDayStatsService;

    @Override
    public void run() {
        String key = RedisKeyBaseBuilder.build("stats", "countryDayStats", "schedule");
        RLock lock = redissonClient.getLock(key);
        try {
            if (lock.tryLock()) {
                LocalDate localDate = LocalDate.now().atStartOfDay(ZoneOffset.ofHours(8)).toLocalDate();
                imCountryDayStatsService.dealWithDailyUserNewData(localDate);
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

}

------------带时区的自定义定时任务--------end--------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
【项目介绍】 基于Java开发的动态定时任务管理系统源码+使用说明.zip 启动 1. csdn下载该项目源码。 2. 本地数据库创建一个名为 `scheduling` 的库。 3. 修改配置文件 `src/main/resources/application.yml`,主要修改数据库连接的用户名和地址。 4. 启动项目。 5. 浏览器访问 `http://localhost:8080`,可以看到如下页面: 功能介绍 1. 项目启动时,会自动从数据库加载状态为 1 的定时任务并开始执行,1 表示处于开启状态的定时任务,0 表示处于禁用状态的定时任务。 2. 点击页面上的**添加作业**按钮,可以添加一个新的定时任务,新任务的 Bean 名称、方法名称以及方法参数如果和已有的记录相同,则认为是重复作业,重复作业会添加失败。 这里涉及到几个参数,含义如下: - Bean 名称:这是项目注入 Spring 的 Bean 名称,测试代码以 `SchedulingTaskDemo.java` 为例。 - 方法名称:参数 1 bean 里边的方法名称。 - 方法参数:参数 2 方法的参数。 - Cron 表达式:定时任务的 Cron 表达式。 - 作业状态:开启和禁用两种。开启的话,添加完成后这个定时任务就会开始执行,禁用的话,就单纯只是将记录添加到数据库。 3. 点击作业编辑,可以修改作业的各项数据: 修改后会立马生效。 4. 点击作业删除,可以删除一个现有的作业。假如删除的作业正在执行,则先停止该作业,然后删除。 5. 点击列表的 switch 按钮也可以切换作业的状态。 ## 技术栈 - SpringBoot - Jpa - MySQL - Spring Job - Vue 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通。 2、项目适用人群:计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等计算机相关专业的在校学生、专业老师、行业内企业员工下载使用。 3、项目可用于:项目本身具有较高的学习借鉴价值,不仅适用于小白学习进阶,也可用于专业人员二次开发。当然也可作为毕设项目、课程设计、课程大作业、初期项目立项演示等。 4、如果基础还行,或者热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载使用,相互学习,共同进步!
Spring Boot通过@EnableScheduling注解来开启定时任务的功能。下面是实现动态定时任务的步骤: 1. 首先,在你的Spring Boot应用的主类上添加@EnableScheduling注解,启用定时任务的支持。例如: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 2. 接下来,在需要执行定时任务的方法上添加@Scheduled注解,并设置定时任务的执行规则。例如,我们可以使用cron表达式来定义定时任务的执行时间。以下是一个示例: ```java import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class MyScheduledTask { @Scheduled(cron = "0 0/5 * * * *") // 每5分钟执行一次 public void doSomething() { // 定时任务要执行的操作 } } ``` 3. 现在,当应用启动后,定时任务会按照定义的规则自动执行。 如果你想在运行时动态地修改定时任务的执行规则,可以借助Spring的ScheduledTaskRegistrar类。可以在应用程序注入ScheduledTaskRegistrar对象,然后使用其方法来注册、取消和修改定时任务。这样你就可以实现动态定时任务调度了。 希望这个回答对你有帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘叶风凌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值