一、项目概述

1.1目的与背景

目前业务系中定时任务采用quartz,定时任务散落在各个业务模块中,为了统一管理我们系统中灵活定时任务的需求,我们需要一套可控的定时任务系统,以便于我们系统未来的产品化。

1.2专用名词解释

executor:代指客户端SDK schedule: 代指服务器端任务调度。

1.3产品需求

  1. 支持多租户模型。
  2. 支持回调。
  3. 提供统一的管理界面,对定时任务进行管理。
  4. 提供启动,暂停,删除,修改接口供业务系统调用。
  5. 提供调度日志。
  6. 任务查询功能。
  7. 任务执行失败通知报警。
  8. 任务调度系统要高可用,支持分布式部署,调度性能能力强劲。
  9. 提供同步调度/异步调度。
  10. 在分布式环境中任务只能被某一个节点执行一次。

1.4关键业务需求

  1. 提供启动,暂停,删除,修改接口供业务系统调用。
  2. 任务查询功能。

二、系统总体设计

2.1系统架构图

介绍

Timer组件主要分为服务器端(调度端)客户端(执行器),服务器用来分发调度执行任务,客户端用来执行任务。

调度端(schedule):调度端负责任务调度,不会与具体的业务耦合,任务执行完毕后,客户端会把任务处理结果发送给调度端。

执行器(execute):执行器负责执行业务代码,服务自动注册。

日志记录:记录任务执行结果。

任务调度一致性:分布式环境中,任务调度确保每次只会有有一台机器执行到任务。

高可用:服务器端和和客户端都支持分布式部署,保证高可用。

任务执行策略:任务执行失败后,支持重试机制。

路由策略:集群环境下多个机器支持不同的调度策略。

服务器端:服务器端任务发送失败后,可以设置任务重试执行次数。

心跳检测:调度端会在链路空闲时间检测服务的可用性。

2.2系统流程图

2.3新技术/技术难点

新技术:java NIO,netty,线程池,异步编程等。链路检测,难点:保证通信平稳,调度任务并行执行时保证机器平稳gc。

三、模块设计

3.1模块设计

3.1.1 execute模块设计

监听模块

监听模块位于客户端,当客户端启动的时候,会异步的创建一个监听服务,用来监听调度端发送的指令,监听模块由netty实现。

服务注册模块

服务注册模块负责应用启动的时候自动注册应用到调度中心,服务器每次调度的时候会选取已经注册的服务发送调度指令,注册模块位于客户端,伴随应用同步启动,当应用启动完成注册完成。

统一注解模块

统一注解模块位于客户端SDK,提供@Timer,@Clock注解,@Timer属性标记这个类为调度类,@Clock注解标记这个方法为调度方法,客户端根据这个两个注解来完成任务调用,@Timer还提供任务调用成功,调用失败的回调接口。

3.1.2 schedule模块设计

调度模块

调度模块采用quartz实现,quartz是一个优秀的开源的调度任务框架,负责任务分发。

指令发送模块

指令发送模块在调度服务器端,由netty实现,netty每次和客户端保持一个长连接,当链路空闲时,会断开和netty server的连接,长连接会每隔30分钟进行一次心跳检测,当链路忙碌时候会复用这个连接。

代理模块

代理模块采用动态代理,当服务器端执行代理方法的时候,实际上执行的是客户端的业务方法,采用JDK的动态代理实现。

查询模块

提供任务调度结果查询,包括应应用地址是否可达,任务调用是否成功,任务执行时间。服务注册查询,机器列表查询。

日志模块

日志模块用来记录job执行结果。

message模块

用来给job的负责人发送任务调度消息,机器检测消息,服务器端检测到所有机器下线,但是还有任务在运行,会进行任务报警给job负责人。

四、数据结构设计

ER图

DB数据流图

Job触发数据流

五、系统HA设计

  1. 路由与心跳服务,通过心跳检测机制,服务器端发现客户端无法服务,通过路由策略会自动调用另一台机器执行定时任务。
  2. 服务器端,和客户端支持分布式部署,通过增加机器,减少单节点故障。
  3. 接入cat打点系统,可以对系统资源监控,发现异常信息管理员收到报警信息。
  4. DB采用主从机制,一旦发现down机可以进行数据切换。

系统运行环境

JDK 1.8

系统截图

系统中等待运行的定时任务: 任务名称

手动添加定时任务或修改任务 任务编辑 服务器端注册的机器列表 客户端注册服务器列表 定时任务执行结果日志 调度日志

特别说明

由于没有sso组件等,系统移除了任务的数据权限控制模块,预留了任务报警接口需要用户自己扩展,移除任务监控模块CAT,用户如果有需求都可以自行扩展。