任务调度理解
Windows && Mac && Linux
- windows
- mac
- linux
操作系统自带的任务调度,主要用于系统服务和简单用户服务
Java原生实现 && Spring Task
模式简单,如果集群部署需要自己解决并发调度问题
Quartz
Quartz 可以使用数据库+抢占式锁的方式解决服务SPOF问题,但是其缺点是调度和执行耦合,长周期持有锁,导致性能受限。
Copy From XXL-JOB
Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题:
问题一:调用API的的方式操作任务,不人性化;
问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务;
问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。
XXL-JOB弥补了quartz的上述不足之处。
XXL-JOB
项目特点:
- 项目代码精简易读,项目文档齐全,非常适合个人企业魔改使用
- CS架构的RPC调度,集群化部署
- 调度中心HA
- 任务HA 丰富的路由策略
- 调度线程池并行调度,内部也设计了快慢线程池,用于避免调度阻塞。
- 通过groovy动态加载类,支持低代码,配置化维护任务能力
com.xxl.job.admin.core.thread.JobScheduleHelper#start
conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();
connAutoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );
preparedStatement.execute();
// tx start
// 1、pre read
long nowTime = System.currentTimeMillis();
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
注:集群情况下如果任务重复执行,可能是由于表初始化时,xxl_job_lock中 'schedule_lock' 没有插入,导致DB锁失效。
具体量化指标:单机能够支撑 5000 任务并发运行稳定运行。
PowerJob
Issue简单说就是根据appid 做了任务拆分,保证一个appid 下的任务只会由一台server执行。。但没文档,源码看的还是不大清晰,例如如何感知到新增或删除节点,达到重分配的效果
企业级任务调度系统
- 企业级海量任务集中调度
- 任务分片
- 高可用设计
- 调度和执行设计
- 节点扩缩容等