quartz实现动态定时任务管理
创始人
2024-11-12 18:08:13
0

1、需求

配置中,固定周期,单位秒。需要任务每间隔这个秒数 执行进行统计。

2、分析

要实现这个需求,之前一直在用的多线程方案也行。详见

既然前面用quartz 根据cron表达式上一次和下一次的执行时间判断。

本次就用quartz来实现动态任务。

毫无疑问,quartz更专业,功能更强大。支持事务,支持任务持久化。事务这边不需要。持久化看产品需求了。

3、编码实现

3.1 QuartzSchedulerConfig

@Configuration public class QuartzSchedulerConfig {      @Bean     public SchedulerFactoryBean schedulerFactory() {         SchedulerFactoryBean factory = new SchedulerFactoryBean();         factory.setBeanName("rules-scheduler");         factory.setOverwriteExistingJobs(true);         factory.setAutoStartup(true);         return factory;     } } 

3.2 FixedCycleSchedule

动态实现新增和删除 - 与数据库记录匹配

public class FixedCycleSchedule {      private static final String GROUP = "fixed";      @Autowired     SchedulerFactoryBean schedulerFactoryBean;        @Scheduled(fixedRate = 60 * 1000)     private void configureTasks() {         log.info("fixed cycle schedule single round start");         Scheduler scheduler = schedulerFactoryBean.getScheduler();         Map map = DbService.getFixedCycle().stream().collect(Collectors.toMap(CustomData::getId, Function.identity()));         try {              List existingList = new ArrayList<>(16);             for (TriggerKey triggerKey : scheduler.getTriggerKeys(GroupMatcher.groupEquals(GROUP))) {                 String taskName = triggerKey.getName();                 if (!map.containsKey(taskName)) {                     System.out.println("remove " + taskName);                     scheduler.unscheduleJob(triggerKey);                     scheduler.deleteJob(JobKey.jobKey(taskName, GROUP));                     continue;                 }                  existingList.add(taskName);             }              List adds = new ArrayList<>(16);             for (String s : map.keySet()) {                 if(!existingList.contains(s)) {                     adds.add(map.get(s));                 }             }              if(!adds.isEmpty()) {                 newTasks(scheduler,adds);             }            } catch (Exception e) {             log.error(e.getMessage());         }           log.info("fixed cycle schedule single round end");     }       private void newTasks(Scheduler scheduler, List adds) throws Exception{          for (CustomData customData : adds) {             JobDetail jobDetail = JobBuilder.newJob(MyJob.class)                     .withIdentity(customData.getId(), GROUP)                     .build();             SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()                     .withIntervalInSeconds(customData.getCycle())                     .repeatForever();              Trigger trigger = TriggerBuilder.newTrigger()                     .withIdentity(customData.getId(), GROUP)                     .startNow()                     .withSchedule(scheduleBuilder)                     .build();             System.out.println("newTasks " + customData.getId());             scheduler.scheduleJob(jobDetail, trigger);         }     }   } 

用spring的schedule每一分钟同步一次。

3.3 Job

public class MyJob implements Job {     @Override     public void execute(JobExecutionContext context) throws JobExecutionException {            // 获取 Trigger         Trigger trigger = context.getTrigger();         TriggerKey key = trigger.getKey();         // 获取 Scheduler         Scheduler scheduler = context.getScheduler();           System.out.println("context.getJobDetail().getKey().getName() = " + key.getName());         System.out.println("Job executed at " + new Date());           SimpleTrigger t = (SimpleTrigger)trigger;         System.out.println("t.getRepeatInterval() = " + t.getRepeatInterval());           try {              if(queryDatabaseForNewSecond == 1) {                 scheduler.pauseTrigger(key);                 scheduler.unscheduleJob(key);             }          } catch (SchedulerException e) {             e.printStackTrace();         }       } }

queryDatabaseForNewSecond==1 可以用来与库中对比,周期配置如有变更,那么需要更新。一开始打算在job中直接更新,更新也是需要停掉,再newScheduleBuilder、newTrigger,再启 。那么直接停掉。外面的FixedCycleSchedule也会再新建

4、结语

Quartz 方式

优点
  1. 高级调度能力

    • Quartz 提供了丰富的调度功能,如固定间隔、固定频率、基于日历的调度等。
    • 可以轻松配置复杂的调度策略,如在特定日期和时间执行任务。
  2. 任务管理

    • 支持任务的暂停、恢复、取消等功能。
    • 可以查看任务的状态,如是否正在执行、何时执行等。
  3. 持久化支持

    • Quartz 可以将调度信息持久化到数据库中,这样即使应用程序重启,调度也不会丢失。
    • 支持集群部署,可以在多个节点之间共享调度信息。
  4. 灵活性

    • 支持多种类型的触发器,如 SimpleTrigger 和 CronTrigger
    • 可以配置多个触发器来调度同一个作业。
  5. 健壮性

    • Quartz 在设计时考虑了高可用性和容错性。
    • 支持故障转移和恢复,可以在任务失败时自动重试。

多线程方式

优点
  1. 简单易用

    • Java 提供了强大的多线程支持,如 Thread 和 Runnable 接口。
    • 可以轻松创建线程并控制线程的生命周期。
  2. 轻量级

    • 相对于 Quartz,多线程模型更为轻量级。
    • 不需要额外的配置或持久化支持。
  3. 灵活的任务执行

    • 可以根据需要自由控制线程的启动和停止。
    • 可以使用 ExecutorService 来管理线程池,提高资源利用率。

择优而用!

相关内容

热门资讯

绝活儿辅助!广东雀神智能插件是... 绝活儿辅助!广东雀神智能插件是真的(辅助挂)其实是有辅助软件(存在有挂)1、广东雀神智能插件是真的公...
绝活辅助!天天爱消除自动消除辅... 绝活辅助!天天爱消除自动消除辅助(辅助挂)一贯是有辅助工具(有挂透明挂);运天天爱消除自动消除辅助辅...
模块辅助!凑一桌关春天怎么才能... 模块辅助!凑一桌关春天怎么才能开挂(辅助挂)果然真的有辅助挂(有挂技术)1、凑一桌关春天怎么才能开挂...
模块辅助!聚友联盟辅助器(辅助... 模块辅助!聚友联盟辅助器(辅助挂)一直真的是有辅助器(证实有挂)1、起透看视 聚友联盟辅助器辅助软件...
指引辅助!途游小程序辅助器(辅... 指引辅助!途游小程序辅助器(辅助挂)果然确实有辅助神器(新版有挂)1、在途游小程序辅助器插件功能辅助...
阶段辅助!手机卡五星辅助软件(... 阶段辅助!手机卡五星辅助软件(辅助挂)确实是真的有辅助方法(确实有挂)1、手机卡五星辅助软件免费辅助...
手段辅助!芒果辅助器安卓版(辅... 手段辅助!芒果辅助器安卓版(辅助挂)原来真的有辅助脚本(有挂解惑)1、这是跨平台的芒果辅助器安卓版轻...
诀窍辅助!免费宝宝浙江游戏安装... 诀窍辅助!免费宝宝浙江游戏安装(辅助挂)竟然真的是有辅助攻略(有挂实锤)1、免费宝宝浙江游戏安装脚本...
办法辅助!透视盒子(辅助挂)一... 办法辅助!透视盒子(辅助挂)一贯是真的有辅助教程(有挂总结)透视盒子辅助器是一种具有地方特色的麻将游...
策略辅助!凑一桌游戏辅助(辅助... 策略辅助!凑一桌游戏辅助(辅助挂)本来真的有辅助插件(有挂技巧)1、点击下载安装,凑一桌游戏辅助脚本...