一条命令部署 XXL-JOB 任务调度中心:Lottery 抽奖系统实战
本文以 Lottery 抽奖系统为例,走通 XXL-JOB 分布式任务调度中心的 Docker 完整部署流程:导入初始化 SQL、拉取镜像、一条命令带参启动。读完即可把项目里"活动状态扫描"和"发货单 MQ 消息补偿"两类定时任务纳入统一调度,并理解每个 PARAMS 参数背后的用意。
先把任务配置存进 MySQL:导入 xxl-job 初始化 SQL
部署调度中心前,先明确一个依赖:XXL-JOB 自身的执行器注册信息、任务定义、调度日志全部落在 MySQL 里,没有可用的 MySQL 实例它跑不起来。Lottery 的部署链路中,MySQL 环境已在上一章节 第04节:部署环境 Mysql 装好(拉取 mysql:latest 镜像、启动容器、建库建表),这里直接做初始化数据的导入。
项目已备好 xxl-job 2.1.2 版本的官方初始化脚本,存放在 doc/assets/sql/xxl-job.sql 路径下,不用自己再找版本。用本地 SQL 客户端连接 MySQL,创建一个名为 xxl_job 的数据库,然后把整个文件导入。
导入后,xxl_job 库会生成这批调度中心赖以运行的核心表:
| 表名 | 职责 |
|---|---|
xxl_job_info | 任务定义表:Cron 表达式、路由策略、阻塞策略、任务参数 |
xxl_job_group | 执行器信息表:AppName、注册方式、地址列表 |
xxl_job_registry | 注册表:执行器心跳上报后在此登记,调度中心据此发现执行器 |
xxl_job_log | 调度日志表:记录每一次触发的执行结果 |
xxl_job_user | 后台登录用户表 |
成功验证:导入后在客户端展开 xxl_job 库,能看到 xxl_job_info、xxl_job_registry 等表(上图红框圈出的部分),说明导入完成。
一条 docker run 完成镜像启动和参数注入
库表就绪后,先拉取官方镜像:
docker pull xuxueli/xxl-job-admin:2.3.0
用 docker images 能确认镜像是否拉取完成;如果拉取报超时错误,可以在 Docker 配置里补充 registry-mirrors 加速地址后重试。
xxl-job-admin 镜像基于 Spring Boot 构建,官方约定通过环境变量 PARAMS 注入启动参数。它本质是追加到 java -jar 之后的命令行参数,优先级高于镜像内 application.properties,所以不改动镜像内任何文件,就能定制端口、数据源和访问令牌:
docker run -e PARAMS=" --server.port=7397 --spring.datasource.url=jdbc:mysql://172.17.0.6:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 --spring.datasource.username=root --spring.datasource.password=123456 --xxl.job.accessToken=xdsl3ewi3al1oehxmo68pqxer" -p 7397:7397 -v /logs/xxl-job:/data/applogs --name xxl-job-admin --restart=always -d xuxueli/xxl-job-admin:2.3.0
⚠️ 命令里的数据库服务器 IP(172.17.0.6)、账号、密码、accessToken 都是作者环境的值,必须替换成你自己的实际值。其中 accessToken 若与执行器侧不一致,执行器后续永远无法注册上来。
把命令拆成两部分看:
| 参数 | 示例值 | 含义 |
|---|---|---|
-e PARAMS="..." | 见上方命令 | Spring Boot 启动参数,镜像唯一的配置入口 |
--server.port | 7397 | 调度中心 HTTP 端口,与 -p 7397:7397 的容器端一致 |
--spring.datasource.url | jdbc:mysql://172.17.0.6:3306/xxl_job... | 数据源,指向刚导入 SQL 的 xxl_job 库 |
--spring.datasource.username/password | root / 123456 | 数据库账号密码,生产环境请换强密码 |
--xxl.job.accessToken | xdsl3ewi3al1oehxmo68pqxer | 调度中心与执行器之间的访问令牌,两边必须一致 |
-p 7397:7397 | 宿主机:容器 | 端口映射,浏览器通过该端口访问后台 |
-v /logs/xxl-job:/data/applogs | 目录映射 | 任务执行日志持久化到宿主机,便于排查 |
--restart=always | — | 进程异常退出或机器重启后自动拉起 |
数据源 URL 里有三个细节值得留意:useUnicode=true 配合 characterEncoding=UTF-8 防止任务名称、日志里的中文乱码;serverTimezone=GMT%2B8 显式声明东八区(即 GMT+8 的 URL 编码形式),MySQL 较新驱动对时区敏感,不指定可能出现时间解析异常,直接影响调度时间的准确性。
启动后三步确认部署成功
容器起来不代表部署完成,按顺序验证:
- 看容器状态:
docker ps | grep xxl-job-admin,确认状态为Up且端口映射显示0.0.0.0:7397->7397/tcp; - 看启动日志:
docker logs xxl-job-admin,出现init xxl-job admin success.字样,说明调度中心与数据源已完成初始化:
- 访问后台:浏览器打开
http://你的服务器IP:7397/xxl-job-admin,用默认账号 admin、密码 123456 登录,首次登录后立即修改默认密码。
外部访问打不开页面时,先检查云服务器安全组和防火墙是否放行了
7397端口——容器内端口通,不等于对外通。
把 Lottery 的定时任务挂上调度
调度中心跑起来只是上半场,应用侧还要完成执行器接入:在 Lottery 工程(Spring Boot)中引入 xxl-job 依赖,配置执行器 AppName、调度中心地址,以及与调度中心一致的 accessToken。应用启动后执行器周期性上报心跳,调度中心通过 xxl_job_registry 表发现并登记它,之后就能在后台为这个 AppName 创建任务。
Lottery 里有两个这样的任务,处理方法都在应用层 worker 包的 LotteryXxlJob 类中:
- 活动状态扫描:把审核通过的活动扫描为"活动中"、已过期活动扫描为"关闭",见 第17节:引入xxl-job处理活动状态扫描;
- 发货单 MQ 消息补偿:扫描发货单消息状态,对未发送或发送失败的 MQ 做补偿重发,见 第18节:扫描库表补偿发货单MQ消息。
配置好 Cron 表达式与路由策略后,两个任务就会出现在任务管理列表中,可查状态、可随时启停:
✅ 至此整条部署链路验证通过:导入 SQL → 拉镜像 → 一条命令启动 → 三步验证。之后新增定时任务,只需在 LotteryXxlJob 里加一个任务方法,再到 xxl-job 后台配置一条调度即可,不用再动其他正在跑的任务。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






