任务调度理解

Windows && Mac && Linux

  1. windows
  2. mac
  3. 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


项目特点:

  1. 项目代码精简易读,项目文档齐全,非常适合个人企业魔改使用
  2. CS架构的RPC调度,集群化部署
  3. 调度中心HA
  4. 任务HA 丰富的路由策略
  5. 调度线程池并行调度,内部也设计了快慢线程池,用于避免调度阻塞。
  6. 通过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执行。。但没文档,源码看的还是不大清晰,例如如何感知到新增或删除节点,达到重分配的效果

企业级任务调度系统

  1. 企业级海量任务集中调度
    • 任务分片
    • 高可用设计
  2. 调度和执行设计
  3. 节点扩缩容等