配置中,固定周期,单位秒。需要任务每间隔这个秒数 执行进行统计。
要实现这个需求,之前一直在用的多线程方案也行。详见
既然前面用quartz 根据cron表达式上一次和下一次的执行时间判断。
本次就用quartz来实现动态任务。
毫无疑问,quartz更专业,功能更强大。支持事务,支持任务持久化。事务这边不需要。持久化看产品需求了。
@Configuration public class QuartzSchedulerConfig { @Bean public SchedulerFactoryBean schedulerFactory() { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setBeanName("rules-scheduler"); factory.setOverwriteExistingJobs(true); factory.setAutoStartup(true); return factory; } }
动态实现新增和删除 - 与数据库记录匹配
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每一分钟同步一次。
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也会再新建
高级调度能力:
任务管理:
持久化支持:
灵活性:
SimpleTrigger
和 CronTrigger
。健壮性:
简单易用:
Thread
和 Runnable
接口。轻量级:
灵活的任务执行:
ExecutorService
来管理线程池,提高资源利用率。择优而用!
上一篇:新2024俱乐部!WEPOKER确实真的是有挂的(透视开挂)wepoker透视软件多少钱(有挂总结)
下一篇:1、R4为ISP,其上只配置IP地址;R4与其他所直连设备间均使用公有IP;2、R3-R5、R6、R7为MGRE环境,R3为中心站点;3、整个OSPF环境IP基于172.16.0.0/16划分