分布式定时任务xxl-job

1. XXL-JOB 的定义与基本概念

1.1 什么是 XXL-JOB?
XXL-JOB 是一款轻量级的分布式任务调度平台,使用 Java 语言开发,由当当网开源。它通过调度中心统一管理和调度分布式执行器上的任务,实现任务的统一调度管理、任务执行监控与调度日志分析等功能。

1.2 核心组成模块

  • 调度中心(Admin): 提供了任务管理、调度、监控以及可视化操作界面。
  • 执行器(Executor): 部署在业务服务所在环境中,用于具体执行调度中心派发的任务。
  • 任务代码: 开发人员编写的定时任务业务逻辑,注册到执行器里,由调度中心下发运行指令。

1.3 XXL-JOB 特点

  • 分布式调度: 易于横向扩容,支持分布式部署多台执行器。
  • 简单易用: 提供了图形化界面,可通过 Web UI 直接管理任务。
  • 易于扩展: 任务执行模式灵活,可以支持多种负载模式,提供一系列的插件扩展。
  • 监控友好: 提供了日志、执行情况、告警等的可视化管理。

2. 常用术语与定时任务时间表达式

在使用 XXL-JOB 之前,我们需要了解一些常见的术语以及它使用的时间表达式规则(一般与 Cron 表达式类似)。

  1. Cron 表达式

    • 它是对时间的一种描述方式,通常由 6 ~ 7 段(XXL-JOB 默认支持 6 段),依次表示 “秒、分、时、日、月、周(年)”。
    • 例如:0 0 12 * * ? 表示每天中午 12 点执行一次。
  2. 调度类型

    • CRON: 常见的 Linux Cron 表达式调度方式。
    • 固定频率: 按固定时间间隔执行,如每隔 10 秒执行一次。
    • 延迟执行: 仅执行一次或延迟执行一次。
  3. 任务分片(分片广播模式)

    • 当任务量较大时,可以将任务分片给多个执行器并行处理,提高任务处理效率。
  4. 失败处理策略

    • 调度失败或执行失败后如何处理:失败告警、重试、终止等。

3. XXL-JOB 与主流定时任务框架对比

目前市面上常见的定时任务框架/平台主要有:QuartzElastic-JobSpring TaskXXL-JOB、以及基于 Kubernetes CronJob 等方式。本节将从主要特性、易用性、扩展性等方面做对比。

对比项 XXL-JOB Quartz Elastic-Job Spring Task Kubernetes CronJob
定位 轻量级分布式任务调度平台,提供可视化操作 经典的 Java 定时任务框架,通常嵌入式使用 分布式弹性调度框架,阿里开源 Spring 提供的简单定时任务调度 容器化、云原生环境下的 Cron 任务调度
可视化界面 自带 Web 管理后台,图形化操作 无,需要自行开发管理界面 需要自行或基于提供的控制台搭建 无原生界面,可通过 Spring Boot Admin 等自行扩展 无需界面,通过 Kubernetes YAML/CLI 配置
分布式调度 支持分布式部署,且本身易于扩容 不原生支持,需要自己实现分布式集群 提供分片、容错、多调度模式 不原生支持分布式,可借助 Spring Cloud 等方式扩展 天生分布式,通过 K8s 集群自身调度
运维友好度 任务监控、日志追踪、告警较完善 需自行整合监控告警组件 提供基本监控,需要额外配置 需自己整合监控告警,封装度有限 依赖 K8s 生态进行监控、告警
上手难度 入门简单,文档完善,接口清晰 学习门槛较高,需要理解 Quartz Trigger、Job 等核心概念 相对中等,需要理解分片机制 较简单,Spring 中注解/配置即可 偏 DevOps,需要熟悉 K8s 对象
适用场景 需要分布式、可视化管理的定时任务场景 单体/简单分布式场景 任务多、分片或弹性伸缩需求场景 小型项目、轻量级调度 云原生场景,大规模容器部署
扩展性 插件丰富,支持多种策略 通过配置和插件可扩展 提供多种可插拔方式 依赖 Spring 生态,功能相对简洁 依赖 K8s 平台生态
维护成本 调度中心集中管理,运维维护相对较低 需要自己做集群化、管理与监控 提供 Elastic Console,但配置稍复杂 统一在 Spring 工程中维护,需注意项目依赖 与 Kubernetes 维护成本相关,适合成熟的 K8s 体系

从上表可以看出:

  • XXL-JOB 相对于其他框架,最大的优势在于 轻量易用图形化管理分布式扩展方便,非常适合需要 “开箱即用” 并且 可视化管理 的分布式任务场景。
  • 缺点 在于需要部署独立的调度中心,需要额外运维一个管理后台以及网络通信(当然,这也带来了更灵活、更专业的管理能力)。

4. 图形化界面展示 XXL-JOB 的操作

XXL-JOB 的 Web 控制台(Admin)的主要功能界面

在 Web 控制台中,你可以:

  1. 添加新任务:配置任务名称、执行器信息、调度方式(CRON 表达式或固定频率等)。
  2. 查看执行器列表:查看当前有哪些执行器实例在运行。
  3. 查看执行日志:任务执行的控制台日志和状态。
  4. 设置告警通知:支持邮件等多种告警方式。

5. 基于 Java-SpringBoot 的 Demo Code

5.1 引入依赖

pom.xml 中添加 XXL-JOB 所需依赖(以 2.3.0 为例,实际根据你使用的版本自行调整):

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

注意:xxl-job 可能会区分执行器端的依赖和调度中心(admin)端的依赖。通常情况下,我们的 Spring Boot 项目是做“执行器”端,所以引入 xxl-job-core 即可。

5.2 在配置文件 application.yml 中进行配置

server:
  port: 8080

spring:
  application:
    name: xxl-job-demo

xxl:
  job:
    # 调度中心配置
    admin:
      addresses: http://127.0.0.1:8081/xxl-job-admin  # XXL-JOB Admin 地址
    # 执行器配置
    executor:
      appname: xxl-job-executor-sample
      port: 9999                     # 执行器端口,默认为0表示随机端口
      ip: 127.0.0.1                  # 可选配置,优先选择该IP注册
    # 日志配置
    log:
      path: /data/applogs/xxl-job    # 任务执行日志保存路径

这里需要先在本地或其他服务器上部署好 XXL-JOB Admin,并确保端口和地址可用。

5.3 编写 XXL-JOB 执行器配置类

在 Spring Boot 中新建一个配置类(例如:XxlJobConfig.java),将执行器加载为 Spring Bean。

@Configuration
public class XxlJobConfig {

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.executor.appname}")
    private String appName;

    @Value("${xxl.job.executor.ip:}")
    private String ip;

    @Value("${xxl.job.executor.port:0}")
    private int port;

    @Value("${xxl.job.accessToken:}")
    private String accessToken;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobSpringExecutor xxlJobExecutor() {
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        return xxlJobSpringExecutor;
    }
}

5.4 编写 Demo 任务 Handler

在 XXL-JOB 中,具体任务通过注解 @XxlJob("任务名称") 来暴露给调度中心。示例如下:

@Component
public class DemoJobHandler {

    /**
     * 简单任务示例:输出日志
     */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        System.out.println("XXL-JOB DEMO: Hello, XXL-JOB! Param=" + param);
        // 返回执行结果
        return ReturnT.SUCCESS;
    }

    /**
     * 另一个任务示例:模拟业务处理
     */
    @XxlJob("demoBusinessJobHandler")
    public ReturnT<String> demoBusinessJobHandler(String param) {
        // 模拟具体业务逻辑处理
        System.out.println("Start business logic...");
        // 省略处理逻辑
        System.out.println("End business logic. Param=" + param);
        return ReturnT.SUCCESS;
    }
}

编译完成后启动项目,该执行器就会自动向 XXL-JOB Admin 注册,调度中心可通过“demoJobHandler”或“demoBusinessJobHandler”这个名称来分配任务进行调度。

5.5 在 XXL-JOB Admin 控制台中配置任务

  1. 登录 XXL-JOB Admin 后台,进入 “任务管理” 菜单,点击 “新建任务”。
  2. 选择对应的执行器名称:xxl-job-executor-sample
  3. 在 “JobHandler” 填写:demoJobHandlerdemoBusinessJobHandler
  4. 配置执行方式:如 CRON 表达式 0/30 * * * * ? 表示每隔 30 秒执行一次。
  5. 保存后即可在任务列表中看到刚刚配置的任务,启动即可。

6. 常用 Cron 表达式示例及在线校验

在编写 Cron 表达式时,建议先在一些 在线 Cron 解析网站(如 pppet.net 等)进行校验,能更直观地查看到触发时间。

以下列举几个常用 Cron:

  1. 每 30 秒执行一次:

    0/30 * * * * ?
    

    含义:从第 0 秒开始,每隔 30 秒触发一次。

  2. 每天晚上 23:00 执行:

    0 0 23 * * ?
    

    含义:每天 23:00:00 执行。

  3. 每周一至周五,早上 9 点执行一次:

    0 0 9 ? * MON-FRI
    

    含义:每周一到周五早上 9:00 执行一次。

  4. 每月 1 号凌晨 1 点执行:

    0 0 1 1 * ?
    

    含义:每个月的 1 号凌晨 1 点执行一次。

pppet.net,你只需将 Cron 表达式贴进去,就能查看到未来的触发时间列表。


总结与技术思考

  1. 为什么选择 XXL-JOB?
    • 如果你需要一个分布式、易扩容、可视化管理的任务调度平台,且对运维成本比较敏感,那么 XXL-JOB 是一个非常合适的选择。
  2. 与其他框架的取舍
    • 如果项目规模较小、单体项目直接使用 Spring Task 可能就足够了。
    • 如果你对作业分片、弹性伸缩有更高要求,并有一定的技术储备,可以考虑 Elastic-Job
    • 如果你已经全面拥抱 K8s,使用 Kubernetes CronJob 也是不错的云原生方案。
  3. 技术痛点与未来升级
    • 需要额外部署和维护调度中心(Admin),但带来的好处是管理和监控更清晰。
    • XXL-JOB 也在不断升级迭代,社区活跃度较高,适合持续使用和二次开发。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容