springboot + schedule
参考文章:https://blog.csdn.net/sinianliushui/article/details/78841713
参考文章: https://blog.csdn.net/hao7030187/article/details/79077464
参考文章:https://www.cnblogs.com/domi22/p/9418433.html
springboot的SchedulerTask相对Quartz来说,简单方便,可试用于小型的job处理。
因没法持久化因此不支持分布式部署,和动态数据源配置。
如果要
一、简易配置
1. 开启定时任务,在启动类添加以下注解
@EnableScheduling
2. 创建并发配置,并发线程
@Component
public class SchedulerConfig implements SchedulingConfigurer { /**
* 设置定时任务
* @param scheduledTaskRegistrar
*/
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool());
}
}
3. 创建scheduler,以下是没5秒触发一次,cron表达式有cron在线生成器可以用
@Component
@Slf4j
public class SchedulerTask { @Scheduled(cron="0/5 * * * * ? ")
public void testTask(){
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.debug(Thread.currentThread() + " " + sdf.format(new Date()));
}
@Scheduled(cron="0/5 * * * * ? ")
public void test2Task(){
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.debug(Thread.currentThread() + " " + sdf.format(new Date()));
}
}
二、分开配置
如下例子,如果只有一个Bean,名字为taskScheduler,或者方法名为taskScheduler则会作为自动的Scheduler。使用 @Scheduled即对应的是此TaskScheduler。
参见文章: https://blog.csdn.net/sinianliushui/article/details/78841713
/**
* description:
* 定时任务
* @Autor:DennyZhao
* @Date:2019/2/15
* @Version: 1.0.0
*/
@Component
@EnableScheduling
public class SchedulerConfig {
/** task相关的属性文件 **/
@Autowired
private TaskProperties taskProperties; /**
* 设备组织用Job
* @return
*/
@Bean("DeviceJob")
public TaskScheduler initDeviceOrgTask(){
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
//线程池大小
scheduler.setPoolSize(taskProperties.getDeviceThreadCount());
//线程名字前缀
scheduler.setThreadNamePrefix("taskThread-deviceTask: ");
scheduler.initialize();
Trigger trigger = new CronTrigger(taskProperties.getDeviceOrgCron());
scheduler.schedule(new DeviceOrgTask(), trigger);
return scheduler;
} /**
* Jpush用Job
* @return
*/
@Bean("JpushJob")
public TaskScheduler initJpushTask(){
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
//线程池大小
scheduler.setPoolSize(taskProperties.getJpushThreadCount());
//线程名字前缀
scheduler.setThreadNamePrefix("taskThread-jpushTask: ");
scheduler.initialize();
Trigger trigger = new CronTrigger(taskProperties.getJpushReportCron());
scheduler.schedule(new JpushReportTask(), trigger);
return scheduler;
}
}
TaskPropertis
/**
* description:
* JPUSH执行任务相关参数
*
* @Autor:DennyZhao
* @Date:2019/2/15
* @Version: 1.0.0
*/
@Component
@PropertySource("classpath:task-config.properties")
@ConfigurationProperties(prefix="task")
@Data
public class TaskProperties { /** 极光推送appKey **/
private String jpushAppKey;
/** 极光推送secretKey **/
private String jpushSecretKey; /** 设备JOB的线程数 **/
private int deviceThreadCount;
/** 设备组织Cron **/
private String deviceOrgCron;
/** Jpush的JOB线程数 **/
private int jpushThreadCount;
/** Jpush的推送报告Cron **/
private String jpushReportCron;
}
创建类实现Runable接口即可使用。
@Component
@Slf4j
public class DeviceOrgTask implements Runnable { @Override
public void run() {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.debug(Thread.currentThread() + " " + sdf.format(new Date()));
}
}
问题:
1. 从以上的一简易配置中(如果不添加SchedulerConfig)也可以运行,发现如果在方法中添加Thread.sleep(),会影响下面方法的运行和下次的运行时间。
因为默认的 ConcurrentTaskScheduler 计划执行器采用Executors.newSingleThreadScheduledExecutor() 实现单线程的执行器。
因此要使用异步: 采用异步的方式执行调度任务,配置 Spring 的 @EnableAsync,在执行定时任务的方法上标注 @Async配置任务执行。注意线程池大小要依据单个任务时间和任务间隔。
2. 分布式重复执行
1.使用 redis分布式锁setnx命令 来控制是否已经存在有任务在执行。
2.使用spring的shedLock,创建一个数据表,先更新者执行,非更新者不执行。
参见:https://segmentfault.com/a/1190000011975027
3. 主程序挂掉后,job停止,数据丢失
使用redis记录执行时间。
异常:
[ERROR] 2019-03-21 14:00:38,757 >>> org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler.handleError(TaskUtils.java:96)
[massage] Unexpected error occurred in scheduled task.
java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@8f84321 has been closed already
使用applicationContext未获取到bean异常。
因EnabledTask会使得任务在执行完后closeContext导致,在配置文件添加:
spring.cloud.task.closecontext_enable=false
高版本用 spring.cloud.task.close_context_enabled=false
参考文章: https://stackoverflow.com/questions/48933575/spring-cloud-task-scheduling-context-closed
springboot + schedule的更多相关文章
- Quartz 和 springboot schedule中的cron表达式关于星期(周几)的不同表示
一.Quartz中cron 表达式分析: quartz 官方源码(org.quartz.CronExpression)解释: Cron expressions are comprised of 6 r ...
- SpringBoot Schedule 配置
1. 定时任务实现方式 定时任务实现方式: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行 ...
- SpringBoot入门教程(九)定时任务Schedule
在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作.比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量.在springboot中可以有很多方案去帮我们完成定时器的工作,有 ...
- springBoot中使用定时任务
简单示例 导入依赖 springBoot已经默认集成了定时任务的依赖,只需要引入基本的依赖就可以使用定时任务. <parent> <groupId>org.springfram ...
- SpringBoot定时任务 - 经典定时任务设计:时间轮(Timing Wheel)案例和原理
Timer和ScheduledExecutorService是JDK内置的定时任务方案,而业内还有一个经典的定时任务的设计叫时间轮(Timing Wheel), Netty内部基于时间轮实现了一个Ha ...
- springboot集成schedule(深度理解)
背景 在项目开发过程中,我们经常需要执行具有周期性的任务.通过定时任务可以很好的帮助我们实现. 我们拿常用的几种定时任务框架做一个比较: 从以上表格可以看出,Spring Schedule框架功能完善 ...
- springboot集成schedule
背景 在项目开发过程中,我们经常需要执行具有周期性的任务.通过定时任务可以很好的帮助我们实现. 我们拿常用的几种定时任务框架做一个比较: 从以上表格可以看出,Spring Schedule框架功能完善 ...
- SpringBoot专题2----springboot与schedule的激情相拥
Schedule:计划,任务.就是我们常说的定时任务.这在我们做一些系统的时候,是经常需要用到的.比如:定时更新一些数据,定时更新索引,都需要这样的一个功能. 第一:创建一个名为springboot- ...
- SpringBoot系列:Spring Boot定时任务Spring Schedule
Spring Schedule是Spring提供的定时任务框架,相较于Quartz,Schedule更加简单易用,在中小型应用中,对于大部分需求,Schedule都可以胜任. 一.Spring Sch ...
随机推荐
- 在<canvas>上绘制img(drawImage())时需要注意的事
<canvas>标签相当于是一个画布,css决定画布的样式(这块画布的背景颜色.大小等),脚本(一般使用JavaScript)就是画笔,我们可以在这个画布上绘制线条.形状.文字.图片等. ...
- PythonStudy——装饰器 Decorator
def outer(func): def inner(): print("新增功能1") func() print("新增功能2") return inner ...
- Yii2 设计模式——工厂方法模式
工厂方法模式 模式定义 工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类吧实例化推迟到子类. 什么意思?说起来有这么 ...
- redis 设置分布式锁要避免死锁
1. jedis 中 setnx key value 虽然可以处理同步问题 (setnx 有返回值 1是key不存在把它设置进去,0是key已经存在了)但是 setnx设置完后 程序的下一步 有可能挂 ...
- abaqus 帮助文档 Substructure(子结构) 理论
对于静态问题,可以缩减到只保留Retain Node的刚度矩阵和载荷矩阵: 但对于动力问题,还需要增加内部节点作为retain node,但这样会有点麻烦,更为常用的方式是保留子结构的模态和振型.
- MySQL运行内存不足时应采取的措施?
排除故障指南:MySQL运行内存不足时应采取的措施? 天一阁@ 老叶茶馆 1周前 导读 排除故障指南:MySQL运行内存不足时应采取的措施? 翻译团队:知数堂藏经阁项目 - 天一阁 团队成员:天一阁- ...
- ubutun 下配置php和postgresql
安装完成后,检查PHP扩展. php -m | grep pdo_pgsql php -m 和phpinfo应该是不同的配置文件, 你在php -m 中能看到的话, 说明你只在php -i|grup ...
- ORC 文件存储格式
1.orc列式存储概念 a)列式存储:orc并不是纯粹的列式存储,也是先基于行对数据表进行分组(行组),然后对行组进行列式存储. b)查询数据的时候不需要扫描全部数据(磁盘IO),只需查询指定列即可. ...
- laravel-admin挖坑之旅
1.git-bash下使用命令php artisan admin:make UserController --model=App\User会报错Model does not exists 要加多一个“ ...
- winrar+目录穿透复现
前言: 学习下该漏洞,记录下这是自动化复现,没有具体分析.菜逼只会用. 00x1: 漏洞简单描述: 该漏洞事一个由UNACEV2.dll代码库中的一个深藏已久的漏洞 当攻击者制作一个恶意的ACE文件时 ...