Scheduled 调度(计划任务)
1、适配方案
两个方案,体验上总体差不多。一些细节上的差别,具体看插件的使用说明。
2、使用预览
启动类上,增加启用注解
// 启用 Scheduled 注解的任务
@EnableScheduling
public class JobApp {
public static void main(String[] args) {
Solon.start(JobApp.class, args);
}
}
注解在类上
// 基于 Runnable 接口的模式
@Scheduled(fixedRate = 1000 * 3)
public class Job1 implements Runnable {
@Override
public void run() {
System.out.println("我是 Job1 (3s)");
}
}
增加拦截处理(如果有需要?),v2.7.2 后支持:
@Slf4j
@Component
public class JobInterceptorImpl implements JobInterceptor {
@Override
public void doIntercept(Job job, JobHandler handler) throws Throwable {
long start = System.currentTimeMillis();
try {
handler.handle(job.getContext());
} catch (Throwable e) {
//记录日志
TagsMDC.tag0("job");
TagsMDC.tag1(job.getName());
log.error("{}", e);
throw e; //别吃掉
} finally {
//记录一个内部处理的花费时间
long timespan = System.currentTimeMillis() - start;
System.out.println("JobInterceptor: job=" + job.getName());
}
}
}
3、注解 Scheduled 属性说明
属性 | 说明 | 备注 |
---|---|---|
cron | 支持7位(秒,分,时,日期ofM,月,星期ofW,年) | 将并行执行 |
zone | 时区:+08 或 CET 或 Asia/Shanghai | 配合 cron 使用 |
fixedRate | 固定频率毫秒数(大于 0 时,cron 会失效) | 将并行执行 |
fixedDelay | 固定延时毫秒数(大于 0 时,cron 和 fixedRate 会失效) | 将串行执行 |
initialDelay | 初次执行延时毫秒数 | 配合 fixedRate 或 fixedDelay 使用 |
不同的适配插件,支持程序略有不同。比如 quartz 不支持 fixedDelay 和 initialDelay(具体看相关插件页)。
4、内部管理接口 IJobManager
IJobManager 是内部管理接口,会在应用容器启动时启动,启动后状态会变成:isStarted() == true
。
public interface IJobManager extends Lifecycle {
//任务添加(不需要再 jobStart)
JobHolder jobAdd(String name, Scheduled scheduled, JobHandler handler);
//任务是否存在
boolean jobExists(String name);
//任务获取
JobHolder jobGet(String name);
//任务移除(会自动停止)
void jobRemove(String name);
//任务开始(jobStop 后,才需要执行 jobStart 重新启动)
void jobStart(String name, Map<String, String> data) throws ScheduledException;
//任务停止
void jobStop(String name) throws ScheduledException;
//是否已启动
boolean isStarted();
}
5、手动控制示例
//也可以被注入(注入,v2.5.6 后支持)
IJobManager jobManager = JobManager.getInstance();
//添加任务
if(jobManager.jobExists("demo") == false){
jobManager.jobAdd("demo" , new ScheduledAnno().fixedRate(1000), (ctx)->{
System.out.printl("Hello job");
});
}
//移除任务
jobManager.jobRemove("demo");