背景
在系统开发过程中,有些任务需要定时触发。这些任务一般可以分为几类:
- 本地进程定时任务,只处理与本进程相关的事情,如定时清理进程缓存、定时扫描监控数据的变化等
- 应用级定时任务,周期较长,只需要一个进程处理就可以了。
- 应用级定时任务,周期短、数据了大,需要应用集群中多个服务器对数据进行分片并行处理。
一般1适合使用进程内Timer直接处理,2/3则需要从全局进行控制。
当前差旅系统主要涉及到1和2,对于2类型的定时任务,一般是单独搭建一套定时任务的双机进行处理,避免麻烦。
比较
对当前比较流行的几种定时任务的框架进行了分析比较,大致如下
定时框架
|
适用场景
|
主要特点
|
参考
|
---|---|---|---|
Spring Schedule | 进程内定时 | 适用注解定义定时任务,通过线程池执行任务 | https://spring.io/guides/gs/scheduling-tasks/ |
Spring Batch | 批量数据处理 | 特点不是在定时,而是多步骤任务流程的编排,数据的转换 | https://docs.spring.io/spring-batch/trunk/reference/html/ |
Elastic Job | 分布式定时处理 | 当当开源,基于Quartz,适用zookeeper进行分布式协调,支持数据分片 | http://elasticjob.io/index_zh.html |
TBSchedule | 分布式定时处理 | 淘宝开源,使用zookeeper进行分布式协调,代码比较老旧了 | http://code.taobao.org/p/tbschedule/wiki/index/ |
XXL-Job | 分布式定时处理 | 美团个人开源,基于Quartz,集中化管理,HTTP远程调用执行器 | http://www.xuxueli.com/xxl-job/ |
从易用性和成本上考虑,XXL-Job是当前最适合我们的定时任务管理框架。
使用XXL-Job
基于XXL-Job,可以采用如下组网方式:
部署一个XXL-Job-Admin和Common-Executor集群,一般的定时任务,就可以在业务侧开放一个HTTP接口,由通用执行器来调用执行即可。复杂的定时任务,可以由业务侧开发业务定时执行器进行处理。
通用执行器
定义好执行器类型后,执行器实例启动后,会自动注册上来。
定时任务
新建定时任务
管理定时任务
查看结果
BugList
序号
|
Bug描述
|
级别
|
备注
|
---|---|---|---|
1 | 执行器进程异常退出(kill -9)会导致任务一直在执行状态,无法终止 | 严重 | 可以通过手工修改数据库中handler结果进行规避 |
2 | 手工可以多次触发执行同一个定时任务,哪怕是串行方式的 | 严重 | 使用“丢弃后续调度”这种策略 |
3 | 手工触发执行,都是提示执行成功,即使是执行器实例列表为空 | 一般 | 应该按实际情况提示,并提示到任务日志页面查看状态 |
优化
1、Spring Boot默认使用tomcat,xxl-job使用Jetty,统一为jetty server。
2、xxl-job-executor默认单独启动一个jetty server,需要单独的端口,修改源码支持使用spring boot的mvc入口,api路径改为/服务名/xxl
3、通用执行期直接支持host和consul服务调用。 如http://服务名/xxxxx,通过服务发现和负载均衡的方式调用url接口。
4、后续有需求,只需要扩展通用执行器能力即可