Dev Guide / Java开发技术guide / 中间件
content/dev-guide/a-Java开发技术guide/04-中间件/5-定时任务.md
- 定时任务常用场景:数据同步、状态扫描、报表生成、缓存刷新、心跳检测、临时修复(一次性补偿处理某段时间的异常数据)等
- 单机定时任务:timer(单线程+优先队列,已淘汰不建议使用)、ScheduledExecutorService(线程池+延时队列)、@scheduled(spring框架提供,支持cron表达式和fixedRate、fixedDelay)
- quartz定时任务(在@scheduled基础上补充了任务持久化、集群调度、事务支持、任务管理API等关键能力)
- Scheduler(调度器):JobDetail(任务定义)、Trigger(触发器,什么时候做,一个JobDetail可以绑定多个Trigger,同一个任务在不同时间点出发)
- 数据库持久化:Quartz的默认存储是内存,服务重启后所有任务丢失。切换到JDBC JobStore后,任务定义和调度状态持久化到数据库
- quartz的局限:无分片能力(一个任务示例只能在一个节点上执行)、无内置监控(排查失败原因只能查数据库和日志)、失败处理薄弱、运维复杂(新增/暂停/删除任务需要代码或直接操作数据库)
- XXL-JOB:轻量级分布式任务调度平台,采用中心化调度设计,有调度中心统一管理和分发任务,执行器负责接收调度指令并执行。
- 核心架构:调度中心(web管理页面、调度引擎:Trigger+Router、注册中心、RPC通信层)-> 执行器(执行任务)
- 调度中心职责:管理所有任务、基于Cron表达式计算任务的触发时间、通过路由策略选择目标执行器、向执行器发送HTTP调度请求并接收执行结果回调、记录任务执行日志、提供Dashboard监控页面和失败告警
- 执行器职责:启动时注册到调度中心、接收调度请求并执行对应的JobHandler、执行完成后调度中心上报结果、无状态设计(执行器不保存任务定义,完全由调度中心下发)
- 核心概念:JobHandler、GLUE类、路由策略(决定将任务分配给哪个执行器的规则,包含FIRST、LAST、ROUND、RANDOM、...)、阻塞处理策略、任务超时、失败重试
- 路由策略选型推荐:FIRST(固定只发给一个执行器)、ROUND(轮询)、FAILOVER(故障转移)、SHARDING_BROADCAST(分片广播)、CONSISTENT_HASH(一致性Hash)
- 分片广播:xxl-job的核心能力,调度中心将任务广播给所有的执行器,每个执行器根据分片参数处理自己负责的数据子集。
- 局限性:中心化调度(调度中心有单点风险)、无动态扩缩容、无作业流编排、弹性能力弱
- elastic-job
- 当当网开源的分布式调度方案,去中心化设计,每个执行节点通过zk协调分片和故障转移
- 去中心化的工作流程:所有节点注册到zk -> 通过zk选出一个leader节点 -> leader负责分片分配给所有在线节点并将分配结果写入zk -> 每个节点从zk读取自己的分片编号,执行对应的数据处理逻辑 -> 故障转移(某节点宕机,zk触发重新选举和分片重分配)-> 宕机节点的分片被分配到健康节点
- 任务分片策略:AverageAllocationJobShardingStrategy、OdevityShardingByNameJobShardingStrategy、RotateServerByNameJobShardingStrategy
- 略
- 方案选型
- 单机模式:任务数量小于10,无分布式需求
- 需要持久化和集群互斥,但不需要分片:quartz+jdbc jobstore
- 需要分片并行处理+可视化+快速落地:xxl-job
- 需要弹性扩缩容+去中心化+系统已有zk:elastic-job
- 需要dag工作流编排+MapReduce并行计算:Powerjob