XXL-Job 任务类型
XXL-Job 支持三种任务类型:Bean 模式、GLUE 模式和 Script 脚本。
三种模式各有特点,适用于不同的场景。今天一起来看。
任务类型概览
┌─────────────────────────────────────────────────────────────┐
│ XXL-Job 任务类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Bean 模式 │ │ GLUE 模式 │ │ Script 脚本 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ 执行 Java 类 在线编写 Java 执行 Shell/Python/ │
│ 代码 PowerShell 等 │
│ │
│ 适用场景: 适用场景: 适用场景: │
│ · 复杂业务逻辑 · 快速迭代 · 系统运维任务 │
│ · 需要编译 · 无需部署 · 现有脚本复用 │
│ · 团队协作 · 临时任务 · 简单脚本 │
│ │
└─────────────────────────────────────────────────────────────┘Bean 模式
原理
Bean 模式是最常用的方式,在执行器中定义一个类,实现 XxlJob 接口:
java
@Component
public class SampleXxlJob extends XxlJobSimpleJob {
@Override
public void execute() throws Exception {
// 这里编写业务逻辑
String param = getJobParam(); // 获取任务参数
int shardIndex = getShardingIndex(); // 获取分片序号
int shardTotal = getShardingTotal(); // 获取分片总数
// 执行业务逻辑
doSomething(param, shardIndex, shardTotal);
}
}注册任务
在调度中心配置:
任务名称:数据同步任务
任务描述:同步订单数据到数据仓库
执行器:order-executor
JobHandler:dataSyncJob
路由策略:FIRST
cron:0 0 2 * * ?
任务参数:2024-01-01执行流程
┌─────────────────────────────────────────────────────────────┐
│ Bean 模式执行流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 调度中心 执行器 │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 找到任务 │ │ │ │
│ │ Handler │ │ │ │
│ │ name │ │ │ │
│ └──────┬──────┘ │ │ │
│ │ │ │ │
│ │ 调用 /run │ │ │
│ ├─────────────────────────▶│ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────┐ │ │
│ │ │ 查找 │ │ │
│ │ │ Handler │ │ │
│ │ │ Bean │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────┐ │ │
│ │ │ 执行任务 │ │ │
│ │ │ execute() │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ │ 回调 /callback │ │ │
│ │◀────────────────────────┤ │ │
│ │ │ │ │
│ ▼ ▼ │ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 记录执行日志│ │ 返回执行结果│ │
│ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘特点
| 优点 | 缺点 |
|---|---|
| ✅ 代码在执行器中,可调试 | ❌ 修改代码需要重新部署 |
| ✅ 支持依赖注入 | ❌ 需要编译 |
| ✅ 可使用执行器的所有 Bean | ❌ 不适合快速迭代 |
| ✅ 类型安全 | ❌ 团队协作需要合并代码 |
GLUE 模式
原理
GLUE 模式允许在调度中心的 Web 界面在线编写和修改代码,实时生效,无需重新部署。
┌─────────────────────────────────────────────────────────────┐
│ GLUE 模式界面 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ GLUE 代码 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ package com.xxl.job.service; │ │
│ │ │ │
│ │ import com.xxl.job.core.context.XxlJobHelper; │ │
│ │ import com.xxl.job.core.handler.IJobHandler; │ │
│ │ │ │
│ │ public class DemoGlueJobHandler extends IJobHandler│ │
│ │ │ │
│ │ @Override │ │
│ │ public void execute() throws Exception { │ │
│ │ String param = XxlJobHelper.getJobParam(); │ │
│ │ XxlJobHelper.log("开始执行,参数:" + param);│ │
│ │ │ │
│ │ // 业务逻辑 │ │
│ │ System.out.println("执行业务逻辑..."); │ │
│ │ │ │
│ │ XxlJobHelper.log("执行完成"); │ │
│ │ } │ │
│ │ } │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [保存] [更新版本] [清空] │
│ │
└─────────────────────────────────────────────────────────────┘GLUE 类型
XXL-Job 支持多种 GLUE 类型:
| 类型 | 说明 | 代码执行方式 |
|---|---|---|
| GLUE_JAVA | Java 代码 | 动态编译 + 反射调用 |
| GLUE_SHELL | Shell 脚本 | Runtime.exec() |
| GLUE_PYTHON | Python 脚本 | Runtime.exec() |
| GLUE_NODEJS | Node.js 脚本 | Runtime.exec() |
| GLUE_PHP | PHP 脚本 | Runtime.exec() |
| GLUE_GO | Go 程序 | Runtime.exec() |
| GLUE_POWERSHELL | PowerShell | Runtime.exec() |
GLUE 代码管理
GLUE 代码会存储在数据库中:
sql
CREATE TABLE xxl_job_info (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
job_group INT NOT NULL COMMENT '执行器分组 ID',
job_cron VARCHAR(128) NOT NULL COMMENT 'cron 表达式',
job_desc VARCHAR(255) DEFAULT NULL,
glue_type VARCHAR(50) DEFAULT NULL COMMENT 'GLUE 类型',
glue_source MEDIUMTEXT COMMENT 'GLUE 源代码',
glue_remark VARCHAR(128) DEFAULT NULL COMMENT 'GLUE 备注',
glue_updatetime DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
-- 其他字段...
);代码更新流程
┌─────────────────────────────────────────────────────────────┐
│ GLUE 代码更新流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 管理员在 Web 界面修改代码 │
│ │
│ 2. 保存到数据库 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ UPDATE xxl_job_info │ │
│ │ SET glue_source = '新代码', │ │
│ │ glue_updatetime = NOW() │ │
│ │ WHERE id = :jobId │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ 3. 下次执行时,加载最新代码 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. 从数据库获取最新 glue_source │ │
│ │ 2. 使用 Groovy/JavaCompiler 编译 │ │
│ │ 3. 创建新的 JobHandler 实例 │ │
│ │ 4. 执行任务 │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ 注意:代码变更后,下次执行才会生效 │
│ │
└─────────────────────────────────────────────────────────────┘特点
| 优点 | 缺点 |
|---|---|
| ✅ 无需重新部署 | ❌ 无法调试(只能看日志) |
| ✅ 实时生效 | ❌ 代码管理困难(没有版本控制) |
| ✅ 适合临时任务 | ❌ 安全性风险(SQL 注入等) |
| ✅ 快速迭代 | ❌ 性能略差(动态编译) |
Script 脚本
原理
Script 模式直接执行脚本文件,适合运维场景:
bash
#!/bin/bash
# 清理日志目录
echo "开始清理日志..."
find /var/log -name "*.log" -mtime +7 -delete
echo "清理完成"
# 返回执行状态
exit 0配置
在调度中心配置:
任务名称:清理日志
任务描述:清理 7 天前的日志文件
执行器:ops-executor
路由策略:FIRST
cron:0 0 3 * * ?
任务类型:GLUE_SHELL执行过程
┌─────────────────────────────────────────────────────────────┐
│ Script 执行过程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 执行器接收到执行命令 │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 1. 获取脚本内容(Bean 从数据库/执行器本地) │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 2. 创建临时脚本文件 │ │
│ │ /tmp/xxl-job/xxl-job-script-xxx.sh │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 3. 设置执行权限 │ │
│ │ chmod +x script-file │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 4. 执行脚本 │ │
│ │ ProcessBuilder /bin/bash script-file │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 5. 收集执行结果和日志 │ │
│ │ stdout → XxlJobHelper.log() │ │
│ │ exit code → 执行状态 │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 6. 删除临时脚本文件 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘特点
| 优点 | 缺点 |
|---|---|
| ✅ 适合运维任务 | ❌ 无法获取业务数据 |
| ✅ 复用现有脚本 | ❌ 无法调试 |
| ✅ 简单易用 | ❌ 错误处理困难 |
| ✅ 无需 Java 知识 | ❌ 安全性风险 |
三种模式对比
| 维度 | Bean 模式 | GLUE 模式 | Script 模式 |
|---|---|---|---|
| 代码管理 | 执行器代码 | 调度中心 | 调度中心 |
| 部署 | 需要重新部署 | 实时生效 | 实时生效 |
| 调试 | 可本地调试 | 日志调试 | 输出调试 |
| 性能 | 高 | 中(编译开销) | 中(进程开销) |
| 依赖注入 | 支持 | 不支持 | 不支持 |
| 适用场景 | 复杂业务 | 快速迭代 | 运维脚本 |
| 安全性 | 高 | 中 | 中 |
| 版本控制 | 支持 | 有限支持 | 不支持 |
选型建议
┌─────────────────────────────────────────────────────────────┐
│ 选型决策树 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 任务类型 │
│ │ │
│ ▼ │
│ 需要复杂业务逻辑? │
│ │ │
│ ├── 是 ──▶ Bean 模式 │
│ │ │
│ └── 否 ──▶ 需要频繁修改代码? │
│ │ │
│ ├── 是 ──▶ GLUE 模式 │
│ │ │
│ └── 否 ──▶ 是运维脚本? │
│ │ │
│ ├── 是 ──▶ Script 模式 │
│ │ │
│ └── 否 ──▶ Bean 模式 │
│ │
└─────────────────────────────────────────────────────────────┘总结
| 模式 | 最佳拍档 | 不适合场景 |
|---|---|---|
| Bean | 复杂业务、需要依赖注入 | 快速迭代 |
| GLUE | 临时任务、快速修复 | 复杂逻辑、生产环境核心任务 |
| Script | 运维任务、现有脚本复用 | 需要业务数据的任务 |
思考题
GLUE 模式可以实时修改代码,但如果修改后的代码有 Bug,导致死循环或内存溢出,怎么办?
如何设计一个安全的 GLUE 执行环境?
