外部统一管理可用 xxl-job ,将各定时任务集中管理,灵活改变执行频率,支持某一个定时器集群处理,避免多服务启动时,每个服务都执行(重复执行)
比如我的API服务里有一个定时任务,将API做成集群时,变成了 API1、API2、API3 ,这时候每个API都有定时任务。但我只能让一个执行,不能也没必要三个API都执行。就只能将定时任务独立成一个 应用发布,或者发布时只开启一个,另外两个不开启。
有了XXL-JOB,1、2、3只会轮训执行一次。
Spring 自带的 Schedule 用法
@Component @EnableScheduling public class CronTask1 { Logger taskLogger = LoggerFactory.getLogger(this.getClass()); /** * @Scheduled除过cron还有三种方式:fixedRate,fixedDelay,initialDelay * cron:表达式可以定制化执行任务,但是执行的方式是与fixedDelay相近的,也是会按照上一次方法结束时间开始算起。 * fixedRate:控制方法执行的间隔时间,是以上一次方法执行完开始算起,如上一次方法执行阻塞住了,那么直到上一次执行完,并间隔给定的时间后,执行下一次。 * fixedDelay:是按照一定的速率执行,是从上一次方法执行开始的时间算起,如果上一次方法阻塞住了,下一次也是不会执行,但是在阻塞这段时间内累计应该执行的次数,当不再阻塞时,一下子把这些全部执行掉,而后再按照固定速率继续执行。 * initialDelay:initialDelay = 10000 表示在容器启动后,延迟10秒后再执行一次定时器。 */ @Scheduled(cron = "*/6 * * * * ?") public void crontabTask() { taskLogger.info("这是基于注解的方式的定时任务" + new Date()); } //内部控制,可加条件判断是否要启用 @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.addTriggerTask(() -> process(), triggerContext -> { //每隔1分钟执行一次 String cron = "10,20 * * * * ?"; return new CronTrigger(cron).nextExecutionTime(triggerContext); }); } private void process() { String info = "这是基于接口的定时任务"; System.out.println(info); taskLogger.info(info); } }
多线程定时任务
@Component @EnableScheduling @EnableAsync public class CronTask3 { Logger taskLogger = LoggerFactory.getLogger("crontabTask_3"); @Async @Scheduled(fixedDelay = 10000) //间隔10秒 public void first() throws InterruptedException { System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName()); taskLogger.info("第一个基于注解设定多线程定时任务"); Thread.sleep(1000 * 10); } @Async @Scheduled(fixedDelay = 20000) public void second() { System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName()); taskLogger.info("第二个基于注解设定多线程定时任务"); } }