cron表达式:https://cron.qqe2.com/
/**
* @EnableScheduling 表示开启定时服务(可标注启动类上 or 定时服务类上)
* @Component 表示交给 spring容器管理 Bean
* @ConditionalOnProperty 控制配置类是否生效
* prefix 配置文件中前缀
* name 配置名
* havingValue 与配置文件中的的值对比,当两个值相同 返回true, 配置类生效
*
* @EnableAsync 表示开启异步任务 (可标注在启动类上 or 定时服务类上)
* @Async 告诉spring这是一个异步方法,spring会开一个线程池进行调用
*
* 备注:
* cron表达式 spring整合只支持 6位,“年” 不支持(默认是当前年)
*/
@Component
@EnableAsync
@EnableScheduling
@ConditionalOnProperty(prefix = "job", name = "enabled", havingValue = "true")
public class xxxJob {
@Autowired
private xxx xxxService;
// @Scheduled(cron = "0 10 * * * ?")
// 每天凌晨 2 点执行
@Async
@Scheduled(cron = "0 0 2 * * ?")
public void execute() {
try{
xxx("*** start -------------->");
Integer num = xxxService.updatexxx();
xxx("*** end ----------------< 【影响行数】:" + num);
} catch (Exception e){
xxx("***服务异常:" + e.getMessage());
}
}
}
# 定时服务是否执行
job.enabled: true
问题一 :
- 基于 @EnableScheduling 定时任务,默认是单线程,对同一个调度任务的执行总是同一个线程,如果任务的执行时间超过该任务的下一次执行时间,则会出现任务丢失,跳> 过该段时间的任务。
解决方案:- 采用异步的方式,配置 Spring 的 @EnableAsync,在执行定时任务的方法上标注 @Async配置任务执行池,线程池大小 n 的数量为 单个任务执行所需时间 / 任务执行的间隔时间
问题二:
分布式情况下,重复执行的问题。
解决方案1:
可用redis的分布式锁, 但分布式跨时区部署的时候,依然无法避免重复执行的问题
解决方案2:
使用shedlock将spring schedule上锁
待续……