在 JDK 8 + PostgreSQL 环境下本地跑通 XXL-JOB(v2.5.0)
适用人群:Java 开发者、任务调度初学者
环境要求:JDK 8、PostgreSQL 10+、Maven、IDE(如 IDEA)
目标成果:本地成功启动 XXL-JOB 调度中心,并连接 PostgreSQL 数据库
一、为什么选择 XXL-JOB?
XXL-JOB 是由许雪里开源的一款轻量级分布式任务调度平台,具备以下优势:
- 开箱即用:提供 Web 控制台,可视化管理任务
- 易扩展:支持多种执行器(Java、Shell、Python 等)
- 高可靠:支持失败重试、告警、分片广播等企业级特性
- 社区活跃:国内广泛使用,文档完善
⚠️ 注意:从 v3.0.0 起,XXL-JOB 要求 JDK 17+ 。
若你仍在使用 JDK 8,请务必选择 v2.5.0 —— 这是最后一个支持 JDK 8 的稳定版本。
二、准备工作
1. 下载源码
前往 XXL-JOB 官网 或 GitHub Release 页面,下载 v2.5.0 版本:
# 比如用git进行clone该项目
git clone --branch 2.5.0-release https://github.com/xuxueli/xxl-job.git
# 或者用TortoiseGit
# URL填入:
https://github.com/xuxueli/xxl-job.git
# 勾选branch并填入:
2.5.0-release
# 进行下载
解压后,使用 IDEA 打开整个项目。
2. 确认环境
- ✅ JDK 8(
java -version验证) - ✅ PostgreSQL 已安装并运行(如
localhost:5432) - ✅ Maven 已配置(用于依赖管理)
三、核心步骤概览
要在 PostgreSQL 中运行 XXL-JOB,需完成以下两件事:
| 步骤 | 说明 |
|---|---|
| 1. 初始化数据库 | 创建 xxl_job 数据库,并导入适配 PostgreSQL 的表结构与初始数据 |
| 2. 配置调度中心 | 修改 xxl-job-admin 模块的数据库连接配置,指向 PostgreSQL |
📌 注意:官方提供的
tables_xxl_job.sql是 MySQL 语法,不能直接用于 PostgreSQL,需进行语法转换。
四、Step 1:初始化 PostgreSQL 数据库
4.1 创建数据库
XXL-JOB 强烈建议使用独立数据库存放调度数据。
在 PostgreSQL 中创建名为 xxl_job 的数据库(可通过 psql、DBeaver 或 Navicat 操作):
-- 创建一个干净、UTF-8 编码、使用最简字符规则、行为可预测的数据库,专供 XXL-JOB 使用,避免因系统区域设置或模板污染导致的兼容性问题。
-- 在 postgres 数据库中执行
CREATE DATABASE xxl_job_pg
ENCODING = 'UTF8'
LC_COLLATE = 'C'
LC_CTYPE = 'C'
TEMPLATE = template0;
4.2 执行建表脚本(PostgreSQL 版)
我们需要在新建立的xxl_job_pg库中,运行创建xxljob必备的表的sql脚本 在运行前请确保当前脚本执行位置在xxl_job_pg里,可以通过
SELECT current_database(); -- 应返回 'xxl_job_pg'
加以验证,在确认当前处于我们新建立的xxl_job_pg库无误后,运行如下的sql脚本
SET client_encoding = 'UTF8';
-- ----------------------------
-- Table structure for xxl_job_info
-- ----------------------------
CREATE TABLE xxl_job_info (
id SERIAL PRIMARY KEY,
job_group INT NOT NULL,
job_desc VARCHAR(255) NOT NULL,
add_time TIMESTAMP DEFAULT NULL,
update_time TIMESTAMP DEFAULT NULL,
author VARCHAR(64) DEFAULT NULL,
alarm_email VARCHAR(255) DEFAULT NULL,
schedule_type VARCHAR(50) NOT NULL DEFAULT 'NONE',
schedule_conf VARCHAR(128) DEFAULT NULL,
misfire_strategy VARCHAR(50) NOT NULL DEFAULT 'DO_NOTHING',
executor_route_strategy VARCHAR(50) DEFAULT NULL,
executor_handler VARCHAR(255) DEFAULT NULL,
executor_param VARCHAR(512) DEFAULT NULL,
executor_block_strategy VARCHAR(50) DEFAULT NULL,
executor_timeout INT NOT NULL DEFAULT 0,
executor_fail_retry_count INT NOT NULL DEFAULT 0,
glue_type VARCHAR(50) NOT NULL,
glue_source TEXT,
glue_remark VARCHAR(128) DEFAULT NULL,
glue_updatetime TIMESTAMP DEFAULT NULL,
child_jobid VARCHAR(255) DEFAULT NULL,
trigger_status SMALLINT NOT NULL DEFAULT 0,
trigger_last_time BIGINT NOT NULL DEFAULT 0,
trigger_next_time BIGINT NOT NULL DEFAULT 0
);
-- ----------------------------
-- Table structure for xxl_job_log
-- ----------------------------
CREATE TABLE xxl_job_log (
id BIGSERIAL PRIMARY KEY,
job_group INT NOT NULL,
job_id INT NOT NULL,
executor_address VARCHAR(255) DEFAULT NULL,
executor_handler VARCHAR(255) DEFAULT NULL,
executor_param VARCHAR(512) DEFAULT NULL,
executor_sharding_param VARCHAR(20) DEFAULT NULL,
executor_fail_retry_count INT NOT NULL DEFAULT 0,
trigger_time TIMESTAMP DEFAULT NULL,
trigger_code INT NOT NULL,
trigger_msg TEXT,
handle_time TIMESTAMP DEFAULT NULL,
handle_code INT NOT NULL,
handle_msg TEXT,
alarm_status SMALLINT NOT NULL DEFAULT 0
);
CREATE INDEX idx_trigger_time ON xxl_job_log (trigger_time);
CREATE INDEX idx_handle_code ON xxl_job_log (handle_code);
CREATE INDEX idx_jobid_jobgroup ON xxl_job_log (job_id, job_group);
CREATE INDEX idx_job_id ON xxl_job_log (job_id);
-- ----------------------------
-- Table structure for xxl_job_log_report
-- ----------------------------
CREATE TABLE xxl_job_log_report (
id SERIAL PRIMARY KEY,
trigger_day TIMESTAMP DEFAULT NULL,
running_count INT NOT NULL DEFAULT 0,
suc_count INT NOT NULL DEFAULT 0,
fail_count INT NOT NULL DEFAULT 0,
update_time TIMESTAMP DEFAULT NULL
);
CREATE UNIQUE INDEX idx_trigger_day ON xxl_job_log_report (trigger_day);
-- ----------------------------
-- Table structure for xxl_job_logglue
-- ----------------------------
CREATE TABLE xxl_job_logglue (
id SERIAL PRIMARY KEY,
job_id INT NOT NULL,
glue_type VARCHAR(50) DEFAULT NULL,
glue_source TEXT,
glue_remark VARCHAR(128) NOT NULL,
add_time TIMESTAMP DEFAULT NULL,
update_time TIMESTAMP DEFAULT NULL
);
-- ----------------------------
-- Table structure for xxl_job_registry
-- ----------------------------
CREATE TABLE xxl_job_registry (
id SERIAL PRIMARY KEY,
registry_group VARCHAR(50) NOT NULL,
registry_key VARCHAR(255) NOT NULL,
registry_value VARCHAR(255) NOT NULL,
update_time TIMESTAMP DEFAULT NULL
);
CREATE UNIQUE INDEX idx_g_k_v ON xxl_job_registry (registry_group, registry_key, registry_value);
-- ----------------------------
-- Table structure for xxl_job_group
-- ----------------------------
CREATE TABLE xxl_job_group (
id SERIAL PRIMARY KEY,
app_name VARCHAR(64) NOT NULL,
title VARCHAR(12) NOT NULL,
address_type SMALLINT NOT NULL DEFAULT 0,
address_list TEXT,
update_time TIMESTAMP DEFAULT NULL
);
-- ----------------------------
-- Table structure for xxl_job_user
-- ----------------------------
CREATE TABLE xxl_job_user (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
role SMALLINT NOT NULL,
permission VARCHAR(255) DEFAULT NULL
);
CREATE UNIQUE INDEX idx_username ON xxl_job_user (username);
-- ----------------------------
-- Table structure for xxl_job_lock
-- ----------------------------
CREATE TABLE xxl_job_lock (
lock_name VARCHAR(50) NOT NULL PRIMARY KEY
);
-- ----------------------------
-- Init data
-- ----------------------------
INSERT INTO xxl_job_group (id, app_name, title, address_type, address_list, update_time)
VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31'::TIMESTAMP);
INSERT INTO xxl_job_info (
id, job_group, job_desc, add_time, update_time, author, alarm_email,
schedule_type, schedule_conf, misfire_strategy, executor_route_strategy,
executor_handler, executor_param, executor_block_strategy, executor_timeout,
executor_fail_retry_count, glue_type, glue_source, glue_remark, glue_updatetime,
child_jobid
) VALUES (
1, 1, '测试任务1', '2018-11-03 22:21:31'::TIMESTAMP, '2018-11-03 22:21:31'::TIMESTAMP, 'XXL', '',
'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0,
'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31'::TIMESTAMP, ''
);
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');
执行该脚本后,xxl_job_pg 数据库将具备完整的调度元数据。
五、Step 2:配置 xxl-job-admin
5.1 定位配置文件
打开项目中的以下文件:
xxl-job/xxl-job-admin/src/main/resources/application.properties
应该会看到类似如下文件:
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root_pwd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
5.2 修改数据库连接
将默认的 MySQL 配置替换为 PostgreSQL 配置:
### 调度数据库配置(PostgreSQL)
spring.datasource.url=jdbc:postgresql://ip:port/xxl_job_pg?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=your_pg_user
spring.datasource.password=your_pg_password
spring.datasource.driver-class-name=org.postgresql.Driver
此时若IDEA中org.postgresql.Driver字段标红,则表面admin的pom中未加载驱动依赖,需要执行下面导入pg Driver的操作
确保 xxl-job-admin 的
pom.xml中已包含 PostgreSQL JDBC 驱动(v2.5.0 默认未引入):<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.3</version> <!-- 适配 JDK8 的较新版本 --> </dependency>
5.3 修改部分mapper
当你配置上述内容后,直接点击启动程序,可能会出现
Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "SECOND"
或者
Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "`"
这是因为xxl-job-admin里的mapper,很多代码都是mysql语句的,pg数据库不支持,所以我们还需要将这些语法都改为pg支持的版本,这块需要变更的代码较多,后续补充
六、启动与验证
- 在 IDEA 中找到
XxlJobAdminApplication.java - 直接运行
main()方法 - 访问 Web 控制台:http://localhost:8080/xxl-job-admin
- 默认账号密码:
admin/123456
✅ 若页面正常打开,且能查看“任务管理”、“执行器管理”,说明部署成功!
七、后续扩展
本文仅覆盖 本地开发环境搭建。后续可继续探索:
- 在虚拟机中部署 XXL-JOB + PostgreSQL
- 使用 Docker Compose 一键启动调度中心与数据库
- 编写自定义执行器(Executor)并注册到调度中心
- 配置邮件告警、任务分片、GLUE 在线编辑等高级功能
八、常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 启动报“表不存在” | 未执行建表脚本 | 确保已执行 PostgreSQL 版初始化 SQL |
| 连接拒绝 | PostgreSQL 未监听或认证失败 | 检查 pg_hba.conf 和 postgresql.conf |
| 驱动类未找到 | 缺少 PostgreSQL JDBC 依赖 | 在 pom.xml 中添加 postgresql 依赖 |
结语
通过本文,你应该已经成功在 JDK 8 + PostgreSQL 环境下跑起了 XXL-JOB 调度中心。虽然官方默认支持 MySQL,但只需稍作调整,PostgreSQL 同样可以完美胜任。
🌟 提示:完整 PostgreSQL 初始化 SQL 脚本与mapper将在下文附上,敬请期待!