企业级项目组件选型(一)分布式任务调度平台

112 阅读5分钟

官网地址:www.xuxueli.com/xxl-job/

能力对比

xxl-jobpowerJobsaturn说明
协议GPLapacheapacheGPL 二次开发之后不能商业化
功能web 控制台有,但是相对有点简单 体验不是很好
触发策略cron 表达式除了cron 还支持 固定评率 固定延迟 以及api 四种定时策略cron 表达式 ,事件触发
分布式计算支持支持支持
在线日志支持支持支持
重试策略支持支持支持
报警邮件,支持扩展邮件 可以支持自定义扩展邮件 支持扩展
用户管理 权限控制支持暂时没有支持
工作流支持配置 父子任务支持
其他性能所有的任务是加锁执行的数据库锁无锁操作依赖zk 做了分布式锁,性能较好
技术成熟度15年开始开发,接入方较多比较少的接入方发展比较早,技术相对复杂,接入方不多
社区发展比较早社区完善20年开始的 发展比较晚 ,不过文档也挺全的看github 还存在一些bug文档比较全
开发效率框架简单 可以支持二次开发代码结构相对复杂一些项目部署复杂 依赖较多上手成本较高
可扩展性1.支持openAPi能力 可扩展性高可以支持代码去写入job2.支持容器能力

能力介绍

架构图

image.png

安全性

为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯; 调度中心和执行器,可通过配置项 “xxl.job.accessToken” 进行AccessToken的设置。 调度中心和执行器,如果需要正常通讯,只有两种设置;

  • 设置一:调度中心和执行器,均不设置AccessToken;关闭安全性校验;
  • 设置二:调度中心和执行器,设置了相同的AccessToken;

权限控制

不同的账号看到的是不同的页面 管理员视角 image.png 普通用户视角 image.png

日志自动清理

XXL-JOB日志主要包含如下两部分,均支持日志自动清理,说明如下:

  • 调度中心日志表数据:可借助配置项 “xxl.job.logretentiondays” 设置日志表数据保存天数,过期日志自动清理
  • 执行器日志文件数据:可借助配置项 “xxl.job.executor.logretentiondays” 设置日志文件数据保存天数,过期日志自动清理;

任务

配置、启动、停止、重试、终止

灰度上线

调度中心与业务解耦,只需部署一次后常年不需要维护。但是,执行器中托管运行着业务作业,作业上线和变更需要重启执行器,尤其是Bean模式任务。

执行器重启可能会中断运行中的任务。但是,XXL-JOB得益于自建执行器与自建注册中心,可以通过灰度上线的方式,避免因重启导致的任务中断的问题。

步骤如下:

  • 1、执行器改为手动注册,下线一半机器列表(A组),线上运行另一半机器列表(B组);
  • 2、等待A组机器任务运行结束并编译上线;执行器注册地址替换为A组;
  • 3、等待B组机器任务运行结束并编译上线;执行器注册地址替换为A组+B组;操作结束;

告警

支持邮件告警,以及预留扩展

接入

1、引入 pom 配置

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.1-SNAPSHOT</version>
</dependency>

2、配置项

### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
xxl.job.executor.appname=xxl-job-executor-sample
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
xxl.job.executor.ip=
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=9999
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=30

3、配置类

@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;
    @Value("${xxl.job.accessToken}")
    private String accessToken;
    @Value("${xxl.job.executor.appname}")
    private String appname;
    @Value("${xxl.job.executor.address}")
    private String address;
    @Value("${xxl.job.executor.ip}")
    private String ip;
    @Value("${xxl.job.executor.port}")
    private int port;
    @Value("${xxl.job.executor.logpath}")
    private String logPath;
    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;
    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        return xxlJobSpringExecutor;
    }
}

4、编写业务代码

@Service
public class DayJob {
    @XxlJob("syncDayJob")
    protected void sync() {
        XxlJobHelper.log("{}", "--- day job begin ----")
        // TODO  do something
        XxlJobHelper.handleFail();
        XxlJobHelper.handleSuccess()
    }
}

后续计划

  • 制作符合团队规范的SpringBoot Starter
  • 针对告警进行扩展,当前只支持邮件,但是日常使用邮件比较少了,需要集成IM能力
  • 服务注册发现环节,当前未和K8S结合,需要考虑结合起来
  • 日志当前存储在Docker容器内,如果实例重启了,日志会丢失,需要改进

总结

  • 轻量
  • 异步
  • 灵活
  • 可视化
  • 配置丰富
  • 不依赖其他中间件
  • 对业务无侵入性