SpringBoot 定时服务

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上锁
待续……

你可能感兴趣的:(SpringBoot 定时服务)