定时任务,不陌生。
一、JDK 原生
java.util.Timer
1. 提供了API 用来提交任务
2.使用while 循环来执行 任务
3. 任务保存在数组中,如果没有任务执行,则 wait
java.util.TimerTask
一个抽象 线程类,用来保证 任务
示例:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.printf("TimerTask exe:"+Thread.currentThread().getName());
}
}, 0, 10 * 1000); // 单位是毫秒
二. Spring 提供的 定时任务
只需要在 方法上加上
@Scheduled
注解,就OK了。 这个用起来非常便捷。
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
在spring boot 项目启动时,这个类会 创建 必要的bean。
org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
会创建一个 ScheduledExecutorService
org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor
后置处理器:
1. 处理 Scheduled 注解的方法
2. 使用 ScheduledExecutorService 执行 task
注意:
线程池默认是 1 个线程,如果要增加线程池个数,可以用配置:
spring.task.scheduling.pool.size
根据自动配置类中
@Bean
@ConditionalOnBean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@ConditionalOnMissingBean({ SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class })
public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
return builder.build();
}
也可以自定义定时执行器:
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
return taskScheduler;
}
三. xxl-job
https://github.com/xuxueli/xxl-job.git/
1. xxl-job 有一个控制台,需要部署之后,用来注册Job。 需要使用到 mysql 数据库
2. 具体的Job 方法写完之后,spring boot项目 使用
@XxlJob
注解标识这个方法,就OK了,也不复杂。
1. 控制台部署
xxljob 依赖 数据库 保存 job的数据信息,所以 首先需要 建库建表。所需要的建表语句 再源码包中已经提供。
数据库配置完成后,直接 部署 控制服务就可以了。就是一个 spring boot 的应用。
默认用户名密码: admin/123456
2. 应用配置
1. 引入依赖包:
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
2. 配置 属性
xxl:
job:
accessToken: default_token
admin:
addresses: http://127.0.0.1:8080/xxl-job-admin
executor:
address: ''
appname: xxl-job-executor-sample
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
3. 添加 注册器bean
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
配置完后,可以开始编写任务:
@XxlJob("doLoadJob")
public void doLoadJob(){
System.out.printf("doLoadJob");
}
功能点:
1. 服务启动后,自动向 控制台注册自己的 地址
2. 控制台注册 任务时,可以选择一种路由策略: 分片广播
分片广播的原理:
拿到 注册的所有的 服务IP,遍历执行 http请求。
对于分片广播,需要 再编写 Job时,完成 分片处理。xxlJob 不会给你的任务做分片,它只是 触发每台服务执行一下任务而已。
对于分片方法,可以自己定义:
任务数%机器数 == 当前机器编号 时,执行
3. 服务接收到任务请求后,会把任务 放在队列中,由 其他的线程异步执行。
四.Quartz
官网:
http://www.quartz-scheduler.org/
在编写代码时,稍微复杂一下,需要实现Job接口,创建 JobDetail、Trigger、Scheduler 等来协助完成调度你的任务。
五、Elastic-Job
需要用到 zookeeper来协助完成。目前为止没有用过。