Skip to content

Docker 部署 XXL-Job 调度中心

概述

XXL-Job 是项目中使用的分布式任务调度平台,用于管理定时任务的注册、调度与监控。

项目中已集成的定时任务:

模块JobHandler说明
HRMpunchRecordGenerateJob每日自动生成打卡记录
HRMemployeeTransferByEffectiveDateJob员工调动生效处理
HRMemployeeResignationByResignationDateJob员工离职生效处理
CRMcustomerAutoPutPoolJob客户自动回收公海
PaypayOrderSyncJob支付订单同步
PaypayOrderExpireJob支付订单过期
PaypayRefundSyncJob退款同步
PaypayNotifyJob支付通知
PaypayTransferSyncJob转账同步
TradetradeOrderAutoCancelJob订单自动取消
TradetradeOrderAutoReceiveJob订单自动收货
TradetradeOrderAutoCommentJob订单自动评价
TradebrokerageRecordUnfreezeJob佣金解冻
PromotioncouponExpireJob优惠券过期
PromotioncombinationRecordExpireJob拼团过期
StatisticstradeStatisticsJob交易统计
StatisticsproductStatisticsJob商品统计
InfraaccessLogCleanJob访问日志清理
InfraerrorLogCleanJob错误日志清理
IoTdeviceOfflineCheckJob设备离线检测
IoTdeviceUpgradeJob设备 OTA 升级
AIaiMidjourneySyncJobMidjourney 绘图同步
AIaiSunoSyncJobSuno 音乐同步
SystemdemoJob示例任务

项目配置信息:

配置项
XXL-Job 版本2.4.0
Admin 地址http://127.0.0.1:9090/xxl-job-admin
执行器 AppNameyudao-server
accessTokendefault_token

前置条件

  • 服务器已安装 Docker
  • MySQL 数据库已部署并可访问(项目中已有 MySQL,直接复用)
  • 确保端口 9090 未被占用

部署步骤

步骤 1:创建 XXL-Job 数据库

XXL-Job Admin 需要一个独立数据库 xxl_job 存储调度信息,不要使用业务库 ruoyi-office

1.1 建库建表(推荐)

优先执行交付包中的脚本(已含建库、8 张表、默认执行器 yudao-server、管理员 admin/123456):

bash
# 路径以工作区为准
mysql -h 127.0.0.1 -P 3306 -uroot -p < ruoyi-office-db/dump/latest/xxl_job_schema.sql

再按版本注册业务定时任务:

bash
# 全功能版
mysql -h 127.0.0.1 -P 3306 -uroot -p < ruoyi-office-db/dump/latest/xxl_job_init_all.sql

# OA 商业版(勿用 init_all)
mysql -h 127.0.0.1 -P 3306 -uroot -p < ruoyi-office-db/dump/latest/xxl_job_init_oa.sql

xxl_job_init_*.sql 只有 INSERT,必须先跑 xxl_job_schema.sql。完整说明见 dump/latest/README.md

1.1b 手工粘贴建表 SQL(备选)

若手头没有上述文件,可登录 MySQL 执行以下 SQL(与 xxl_job_schema.sql 等价主体):

sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS `xxl_job` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

USE `xxl_job`;

-- xxl_job_info 任务信息表
CREATE TABLE `xxl_job_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
  `job_desc` varchar(255) NOT NULL,
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `author` varchar(64) DEFAULT NULL COMMENT '作者',
  `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
  `schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
  `schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
  `misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
  `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
  `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
  `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
  `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
  `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
  `trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
  `trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
  `trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_log 任务调度日志表
CREATE TABLE `xxl_job_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
  `job_id` int(11) NOT NULL COMMENT '任务主键ID',
  `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
  `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
  `trigger_code` int(11) NOT NULL COMMENT '调度-结果',
  `trigger_msg` text COMMENT '调度-日志',
  `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
  `handle_code` int(11) NOT NULL COMMENT '执行-状态',
  `handle_msg` text COMMENT '执行-日志',
  `alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
  PRIMARY KEY (`id`),
  KEY `I_trigger_time` (`trigger_time`),
  KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_log_report 任务调度日志报表
CREATE TABLE `xxl_job_log_report` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
  `running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
  `suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
  `fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_trigger_day` (`trigger_day`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_logglue GLUE日志表
CREATE TABLE `xxl_job_logglue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_id` int(11) NOT NULL COMMENT '任务主键ID',
  `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_registry 执行器注册表
CREATE TABLE `xxl_job_registry` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `registry_group` varchar(50) NOT NULL,
  `registry_key` varchar(255) NOT NULL,
  `registry_value` varchar(255) NOT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_group 执行器信息表
CREATE TABLE `xxl_job_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
  `title` varchar(12) NOT NULL COMMENT '执行器名称',
  `address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
  `address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_user 用户表
CREATE TABLE `xxl_job_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '账号',
  `password` varchar(50) NOT NULL COMMENT '密码',
  `role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
  `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分隔',
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- xxl_job_lock 任务锁表
CREATE TABLE `xxl_job_lock` (
  `lock_name` varchar(50) NOT NULL COMMENT '锁名称',
  PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 初始化默认管理员账号(admin/123456)
INSERT INTO `xxl_job_group` (`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`)
VALUES (1, 'yudao-server', 'RuoYi Office', 0, NULL, NOW());

INSERT INTO `xxl_job_user` (`id`, `username`, `password`, `role`, `permission`)
VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);

INSERT INTO `xxl_job_lock` (`lock_name`) VALUES ('schedule_lock');

COMMIT;

💡 注意:初始化数据中已包含 yudao-server 执行器,无需手动添加。

方式 2:从 GitHub 下载

bash
# 下载 XXL-Job 2.4.0 官方建表 SQL
curl -o tables_xxl_job.sql https://raw.githubusercontent.com/xuxueli/xxl-job/2.4.0/doc/db/tables_xxl_job.sql

1.2 执行建表 SQL

如果 MySQL 运行在 Docker 中:

bash
# 将 SQL 文件复制到 MySQL 容器内
docker cp tables_xxl_job.sql mysql:/tmp/

# 进入 MySQL 执行
docker exec -it mysql mysql -uroot -p'你的MySQL密码'

# 在 MySQL 命令行中执行
source /tmp/tables_xxl_job.sql;

如果使用 MySQL 客户端连接:

bash
mysql -h 127.0.0.1 -P 3306 -uroot -p'你的MySQL密码' < tables_xxl_job.sql

1.3 验证数据库

bash
docker exec -it mysql mysql -uroot -p'你的MySQL密码' -e "USE xxl_job; SHOW TABLES;"

应看到以下 8 张表:

+--------------------+
| Tables_in_xxl_job  |
+--------------------+
| xxl_job_group      |
| xxl_job_info       |
| xxl_job_lock       |
| xxl_job_log        |
| xxl_job_log_report |
| xxl_job_logglue    |
| xxl_job_registry   |
| xxl_job_user       |
+--------------------+

步骤 2:Docker 部署 XXL-Job Admin

2.1 拉取镜像

bash
# 方式 1:直接拉取(需配置镜像加速器或网络通畅)
docker pull xuxueli/xxl-job-admin:2.4.0

# 方式 2:使用国内镜像源
docker pull registry.cn-hangzhou.aliyuncs.com/xuxueli/xxl-job-admin:2.4.0
docker tag registry.cn-hangzhou.aliyuncs.com/xuxueli/xxl-job-admin:2.4.0 xuxueli/xxl-job-admin:2.4.0

# 方式 3:手动导入(网络不通时)
# 在有网络的机器上执行:
# docker pull xuxueli/xxl-job-admin:2.4.0
# docker save xuxueli/xxl-job-admin:2.4.0 -o xxl-job-admin-2.4.0.tar
# 传输到服务器后导入:
# docker load -i xxl-job-admin-2.4.0.tar

验证镜像:

bash
docker images | grep xxl-job

2.2 创建日志目录

bash
mkdir -p /data/xxl-job/logs

2.3 启动 XXL-Job Admin 容器

⚠️ 请根据实际情况修改以下参数:

  • MySQL 地址(如 MySQL 也在同一台 Docker 宿主机,可用 host.docker.internal 或宿主机内网 IP)
  • MySQL 用户名和密码
  • accessToken 需与后端项目配置保持一致(项目默认 default_token

场景 A:MySQL 在同一台宿主机的 Docker 中运行

bash
# 获取宿主机内网 IP(用于容器间通信)
HOST_IP=$(hostname -I | awk '{print $1}')
echo "宿主机 IP: $HOST_IP"

docker run -d \
  --name xxl-job-admin \
  --restart always \
  -p 9090:8080 \
  -v /data/xxl-job/logs:/data/applogs \
  -e TZ=Asia/Shanghai \
  -e PARAMS=" \
    --spring.datasource.url=jdbc:mysql://${HOST_IP}:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai \
    --spring.datasource.username=root \
    --spring.datasource.password=你的MySQL密码 \
    --xxl.job.accessToken=default_token \
    --xxl.job.logretentiondays=30 \
  " \
  xuxueli/xxl-job-admin:2.4.0

场景 B:MySQL 在远程服务器

bash
docker run -d \
  --name xxl-job-admin \
  --restart always \
  -p 9090:8080 \
  -v /data/xxl-job/logs:/data/applogs \
  -e TZ=Asia/Shanghai \
  -e PARAMS=" \
    --spring.datasource.url=jdbc:mysql://MySQL服务器IP:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai \
    --spring.datasource.username=root \
    --spring.datasource.password=你的MySQL密码 \
    --xxl.job.accessToken=default_token \
    --xxl.job.logretentiondays=30 \
  " \
  xuxueli/xxl-job-admin:2.4.0

场景 C:本地开发环境(Windows / Mac)

bash
docker run -d \
  --name xxl-job-admin \
  --restart always \
  -p 9090:8080 \
  -v xxl-job-logs:/data/applogs \
  -e TZ=Asia/Shanghai \
  -e PARAMS=" \
    --spring.datasource.url=jdbc:mysql://host.docker.internal:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai \
    --spring.datasource.username=root \
    --spring.datasource.password=你的MySQL密码 \
    --xxl.job.accessToken=default_token \
    --xxl.job.logretentiondays=30 \
  " \
  xuxueli/xxl-job-admin:2.4.0

💡 Windows/Mac 上 Docker 容器访问宿主机 MySQL:使用 host.docker.internal 代替 127.0.0.1

2.4 验证启动

bash
# 检查容器状态
docker ps | grep xxl-job-admin

# 查看启动日志
docker logs -f xxl-job-admin --tail 100

# 等待出现类似日志表示启动成功:
# 2026-xx-xx ... Started XxlJobAdminApplication in x.xxx seconds

2.5 访问管理界面

浏览器打开:

http://服务器IP:9090/xxl-job-admin

本地开发环境:

http://127.0.0.1:9090/xxl-job-admin

默认登录账号:

账号密码
admin123456

步骤 3:修改后端项目配置

打开 yudao-server/src/main/resources/application-local.yaml,找到 XXL-Job 配置段,将 enabled 改为 true

yaml
--- #################### 定时任务相关配置 ####################

xxl:
  job:
    enabled: true  # ← 改为 true,开启 XXL-Job 执行器
    admin:
      addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心地址

⚠️ 如果 XXL-Job Admin 部署在远程服务器,需修改 addresses 为对应 IP 地址。

修改完成后 重启后端服务


步骤 4:配置执行器

重启后端服务后,执行器会自动注册到 XXL-Job Admin。

4.1 验证执行器注册

  1. 登录 XXL-Job Admin(http://127.0.0.1:9090/xxl-job-admin
  2. 进入 执行器管理 菜单
  3. 应看到已注册的执行器:
AppName名称注册方式机器地址
yudao-serverRuoYi Office自动注册192.168.x.x:9999

如果执行器未自动出现,点击 新增 手动添加:

  • AppNameyudao-server(必须与配置一致)
  • 名称RuoYi Office
  • 注册方式:自动注册

步骤 5:配置定时任务

5.1 添加任务

任务管理 菜单中,选择执行器 RuoYi Office,点击 新增

每日自动生成打卡记录 为例:

配置项
执行器RuoYi Office
任务描述每日自动生成打卡记录
负责人admin
路由策略第一个
Cron0 5 0 * * ?
运行模式BEAN
JobHandlerpunchRecordGenerateJob
阻塞处理策略单机串行
任务超时时间0
失败重试次数1

点击 保存

5.2 常用任务配置参考

任务描述JobHandler建议 Cron说明
每日自动生成打卡记录punchRecordGenerateJob0 5 0 * * ?每天 00:05
员工调动生效处理employeeTransferByEffectiveDateJob0 0 1 * * ?每天 01:00
员工离职生效处理employeeResignationByResignationDateJob0 30 1 * * ?每天 01:30
客户自动回收公海customerAutoPutPoolJob0 0 2 * * ?每天 02:00
支付订单同步payOrderSyncJob0 0/1 * * * ?每分钟
支付订单过期payOrderExpireJob0 0/1 * * * ?每分钟
退款同步payRefundSyncJob0 0/1 * * * ?每分钟
支付通知payNotifyJob0 0/1 * * * ?每分钟
访问日志清理accessLogCleanJob0 0 3 * * ?每天 03:00
错误日志清理errorLogCleanJob0 0 4 * * ?每天 04:00

5.3 启动任务

在任务列表中,点击任务右侧的 启动 按钮。

也可以点击 执行一次 立即测试任务是否正常执行。


故障排查

执行器注册不上

现象:执行器管理中看不到 yudao-server,或机器地址为空。

排查步骤

bash
# 1. 确认后端 xxl.job.enabled 为 true
grep -A 5 "xxl:" yudao-server/src/main/resources/application-local.yaml

# 2. 确认 Admin 地址配置正确
# addresses 需要能从后端服务访问到

# 3. 确认 accessToken 一致
# Admin 容器启动参数中 --xxl.job.accessToken=default_token
# 后端配置 xxl.job.accessToken: default_token

# 4. 查看后端启动日志,搜索 xxl-job 相关
# 正常应该看到:
# >>>>>>>>>>> xxl-job register jobhandler success, name:punchRecordGenerateJob

Admin 启动失败

bash
# 查看容器日志
docker logs xxl-job-admin

# 常见错误:
# 1. 数据库连接失败 → 检查 MySQL 地址、用户名、密码
# 2. Access denied → 检查 MySQL 用户权限
# 3. Unknown database 'xxl_job' → 建表 SQL 未执行

任务执行失败

  1. 调度日志 中查看具体错误信息
  2. 常见原因:
    • 调度成功,执行失败:检查后端业务逻辑日志
    • 调度失败:执行器不在线,检查注册状态
    • 路由策略异常:只有一个执行器实例时使用 "第一个" 策略

容器管理常用命令

bash
# 查看容器状态
docker ps | grep xxl-job-admin

# 查看日志
docker logs -f xxl-job-admin --tail 200

# 重启容器
docker restart xxl-job-admin

# 停止并删除容器
docker stop xxl-job-admin
docker rm xxl-job-admin

# 重新部署(修改配置后)
docker stop xxl-job-admin && docker rm xxl-job-admin
# 然后重新执行 docker run 命令

服务地址速查

服务地址账号
XXL-Job Adminhttp://服务器IP:9090/xxl-job-adminadmin / 123456
后端 APIhttp://服务器IP:48080-

注意事项

  1. 版本对齐:XXL-Job Admin 版本必须与项目依赖版本一致,当前为 2.4.0
  2. Token 一致:Admin 的 --xxl.job.accessToken 必须与后端配置 xxl.job.accessToken 一致(默认 default_token
  3. 时区设置:Admin 容器已通过 -e TZ=Asia/Shanghai 设置为东八区,确保 Cron 表达式按北京时间调度
  4. 日志保留--xxl.job.logretentiondays=30 设置日志保留 30 天,可根据磁盘空间调整
  5. 多环境部署:生产环境建议将 accessToken 修改为复杂随机字符串
联系我们

获取报价、演示和二开方案

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版