记 springboot 定时任务踩坑
配置 定时任务 流程
-
在SimApplication.java 上面添加 @EnableScheduling 注解
@SpringBootApplication @EnableScheduling @MapperScan("com.jointcontrols.sim.dao") public class SimApplication { public static void main(String[] args) { SpringApplication.run(SimApplication.class, args); } }
-
创建定时任务 类 加注解@Component 在定时任务方法上加注解@Scheduled
package com.jointcontrols.sim.service; import com.alibaba.fastjson.JSON; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.jointcontrols.sim.base.PageResult; import com.jointcontrols.sim.constants.ChinaMobileSimManagerConstant; import com.jointcontrols.sim.dao.ExpensesDao; import com.jointcontrols.sim.dao.SimManagerDao; import com.jointcontrols.sim.model.Expenses; import com.jointcontrols.sim.model.SimMonthFee; import com.jointcontrols.sim.model.SimMonthFeeDetails; import com.jointcontrols.sim.model.SingleSimInfo; import com.jointcontrols.sim.model.chinamobile.*; import com.jointcontrols.sim.utils.CommonUtils; import com.jointcontrols.sim.utils.PageUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; /** * 资费查询Service * * @author HyoJung */ @EnableScheduling @Service @Slf4j public class ExpensesService { @Autowired private SimManagerDao simManagerDao; @Autowired private ExpensesDao expensesDao; @Scheduled(initialDelay =0 , fixedRateString = "${sim.config.sync86400Interval}") private void queryMemberMonthFeeBatch() { log.info("执行定时任务queryMemberMonthFeeBatch......."); if (!CommonUtils.isLastTenDayOfMonth()) { return; } int pageSize = 100; long totalPages = 1; for (int i = 1; i <= totalPages; i++) { //.... ..... 略 太长了 } }
注:因为定时任务写在service中了 所以 类上面 注解 加的是@Service
填坑
-
@Scheduled 注解: 参数
参考package org.springframework.scheduling.annotation.cheduled.class
package org.springframework.scheduling.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(Schedules.class) public @interface Scheduled { String CRON_DISABLED = "-"; String cron() default ""; String zone() default ""; long fixedDelay() default -1L; String fixedDelayString() default ""; long fixedRate() default -1L; String fixedRateString() default ""; long initialDelay() default -1L; String initialDelayString() default ""; }
cron : cron表达式
zone: 时区
fixedDelay: 上次执行定时任务结束后 多久以后再执行
fixedDelayString: 与fixedDelay 意思相同, 唯一不同 支持占位符:fixedDelayString = “${sim.config.sync86400Interval}”
fixedRate:上次执行定时任务开始后 多久在执行 (可能不等上次定时任务执行完,导致重复执行问题)
fixedRateString: 与fixedRate y意思相同 唯一不同 支持占位符:fixedRateString= “${sim.config.sync86400Interval}”
initialDelay: 容器初始化之后 多久第一次执行定时任务
initialDelayString: 与initialDelay 意思相同,唯一不同 支持占位符:fixedRateString= “${sim.config.sync86400Interval}”
-
定时任务不执行
springboot执行 定时任务 scheduled 本身在单线程中, 如果 定时任务非常多的情况下,会导致线程阻塞
解决办法:
添加 配置类
package com.jointcontrols.sim.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import java.util.concurrent.Executors; /** * ClassName: ScheduleConfig <br/> * Description: <br/> * date: 2022/2/11 10:03<br/> * * @author Hwq <br/> * @since JDK 1.8 */ @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { // 设置线程池 scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5)); } }
此外: 还有几种方法(未尝试)
参考大佬文章链接:https://blog.csdn.net/liaoyi9203/article/details/109842925