XXL-Job工具使用操作记录

官网:https://www.xuxueli.com/xxl-job/

环境配置

假设目前已配置好如下环境:

Windows:JDK、Git、IDEA、Maven、Python

Linux:JDK、Kettle

gitee仓库地址

复制代码
https://gitee.com/xuxueli0323/xxl-job

克隆仓库

shell 复制代码
# 默认克隆最新版本,只支持jdk17
git clone https://gitee.com/xuxueli0323/xxl-job.git

# 指定克隆版本,2.5.0支持jdk8
git clone -b 2.5.0 https://gitee.com/xuxueli0323/xxl-job.git

执行sql文件

克隆项目后,找到xxl-job\doc\db\tables_xxl_job.sql,在数据库执行即可。

注:目前xxl-job 2.5.0版的tables_xxl_job.sql是mysql语法,若需要支持其他数据库,需要自己改一下sql文件语法,并且在项目pom.xml中引入其他数据库的驱动等。

修改配置

调度中心和执行器说明

xxl-job分调度中心执行器,其中对比说明如下表:

对比维度 调度中心 (Admin) 执行器 (Executor)
核心角色 调度大脑 - 任务调度指挥中心 执行终端 - 任务具体执行节点
主要职责 1. 任务调度决策 2. 任务管理(增删改查) 3. 调度触发 4. 执行器管理 5. 日志监控 1. 任务实际执行 2. 业务逻辑处理 3. 心跳注册 4. 执行结果反馈
功能定位 管理控制层 - 负责"何时执行"和"分配给谁" 业务执行层 - 负责"如何执行"
部署方式 独立部署,通常一个项目只需一个调度中心(支持集群) 集成部署,每个需要执行任务的服务都需部署执行器
数据存储 依赖数据库(MySQL等),存储任务配置、日志等 不依赖数据库(除非业务需要),本地内存运行
通信方向 主动调用 → 向执行器发送调度请求 被动响应 ← 接收调度请求并返回结果
集群模式 中心化集群:多个调度中心实例共用同一个数据库,通过数据库锁避免重复调度 分布式集群:多个执行器实例注册到同一个调度中心,负载均衡执行任务
典型配置 端口:8080(默认) 数据库:MySQL Web界面:提供管理控制台 端口:9999(默认) AppName:执行器名称(唯一标识) 注册地址:自动/手动注册
工作流程 1. 解析任务Cron表达式 2. 到达触发时间 3. 选择合适的执行器 4. 发送HTTP请求调用任务 5. 记录执行日志 1. 启动时向调度中心注册 2. 接收调度请求 3. 通过反射调用本地JobHandler 4. 执行业务代码 5. 返回执行结果
关键配置 spring.datasource.url spring.datasource.username spring.datasource.password spring.datasource.driver-class-name xxl.job.accessToken xxl.job.i18n xxl.job.admin.addresses xxl.job.admin.accessToken xxl.job.executor.appname xxl.job.executor.port
调度中心

目前演示克隆的是xxl-job 2.5.0版本,并且数据库也是mysql。

使用IDEA打开xxl-job项目,打开xxl-job-admin/src/main/resources/application.properties,如下,需修改数据库配置信息等。

properties 复制代码
### web【启动端口】
server.port=8080
server.servlet.context-path=/xxl-job-admin

### actuator
management.server.base-path=/actuator
management.health.mail.enabled=false

### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static/

### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
spring.freemarker.settings.new_builtin_class_resolver=safer

### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml

### datasource-pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=900000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.validation-timeout=1000

### xxl-job, datasource【必须修改,需自行手动修改】
spring.datasource.url=jdbc:mysql://192.168.88.199:3306/xxl_job_8?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

### xxl-job, email【可选,配置邮箱发送地址】
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.from=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

### xxl-job, access token【可选,默认token,需与执行器的保持一致】
xxl.job.accessToken=default_token

### xxl-job, access token
xxl.job.timeout=3

### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")【可选,默认语言是简体中文,zh_TC:繁体中文,en:英文】【或者通过启动的时候进行指定】
xxl.job.i18n=zh_CN

## xxl-job, triggerpool max size
# 快速线程池的最大线程数,默认为200。
xxl.job.triggerpool.fast.max=200
# 慢速线程池的最大线程数,默认为100
xxl.job.triggerpool.slow.max=100

### xxl-job, log retention days
# 日志默认过期天数
xxl.job.logretentiondays=30

至少要修改### xxl-job, datasource的数据库连接信息,也就是执行sql文件的数据库信息。

执行器

打开xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties,需修改如下配置信息等。

properties 复制代码
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"【指定部署调度中心的地址,比如将调度中心部署在192.168.88.199这台服务器】
xxl.job.admin.addresses=http://192.168.88.199:8080/xxl-job-admin
### xxl-job, access token【可选,默认token,需与调度中心的保持一致】
xxl.job.admin.accessToken=default_token

修改完配置后,可以直接在IDEA分别启动调度中心执行器查看是否正常,即xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.javaxxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/XxlJobExecutorApplication.java

使用Maven进行打包

因为后期在服务器上进行部署是执行jar包的方式,故以上配置完,即可进行打包,直接在IDEA中进行打包。

或者在终端输入mvn package命令来进行打包。

打包完成后,找到打包的jar包,分两个,一个是调度中心,一个是执行器

部署服务

因为目前需要进行搭建服务,计划将调度中心部署在Linux服务器上,执行器在Linux和Windows上各自部署一个。

说明 IP地址
调度中心IP 192.168.88.199
执行器IP(Linux) 192.168.88.199
执行器IP(Windows) 10.181.176.27

注:执行器可配置一到多个,看自己需求。

将jar包使用FinalShell上传到Linux,

启动服务

Linux上需要进行启动调度中心执行器,采用后台运行。

shell 复制代码
cd /usr/local/xxl-job

# 1. 启动调度中心
nohup java -jar xxl-job-admin-2.5.0.jar > admin.log 2>&1 &

# 1. 启动调度中心(或指定显示语言为繁体中文)
# nohup java -jar xxl-job-admin-2.5.0.jar --xxl.job.i18n=zh_TC > admin.log 2>&1 &

# 2. 启动执行器  
nohup java -jar xxl-job-executor-sample-springboot-2.5.0.jar > executor.log 2>&1 &

# 若8080端口未开放,则进行如下处理
# 查看开放的端口:
firewall-cmd --zone=public --list-ports

# 开放指定端口:
firewall-cmd --zone=public --add-port=8080/tcp --permanent

# 立即生效:
firewall-cmd --reload

Windows需进行启动执行器,同样采用后台运行。

进入xxl-job-executor-samples\xxl-job-executor-sample-springboot\target目录下,打开PowerShell,直接执行如下命令:

powershell 复制代码
# 在PowerShell中运行
Start-Process -WindowStyle Hidden -FilePath "java" -ArgumentList "-jar xxl-job-executor-sample-springboot-2.5.0.jar" -RedirectStandardOutput "executor.log" -RedirectStandardError "error.log"

关闭服务

Linux关闭调度中心执行器

shell 复制代码
# 查看进程(精确过滤)
ps -ef | grep xxl-job

# 强制结束
kill -9 进程ID

Windows关闭执行器

powershell 复制代码
# 在PowerShell中运行,查看进程ID
Get-CimInstance Win32_Process -Filter "name='java.exe'" | Where-Object { $_.CommandLine -like "*xxl-job-executor-sample-springboot-2.5.0.jar*" }

# 强制结束
Stop-Process -Id 进程ID -Force

管理控制台

以上启动服务器后,即可进入管理控制台,在本地浏览器访问http://192.168.88.199:8080/xxl-job-admin/toLogin

默认账号:admin

默认密码:123456

ip地址为启动调度中心所在服务器地址

点击登录即可查看

注:以上运行报表信息为之前配置的,若第一次使用,则此处相关数据为空。

配置执行器

登录管理控制台后,第一步就是配置执行地址,因为部署了2个执行器,故此处需要进行配置。

点击【新增】

同理再新增一个windows的执行器,

2个执行器均配置完成如下:

任务管理

Linux执行器相关任务

为测试功能是否正常,点击任务管理->新增,此处测试运行模式为GLUE(Shell)是否正常,点击保存。

点击操作的GLUE IDE,进行编辑

注:默认新增任务的状态是STOP ,若需要使CRON表达式生效来定时执行任务的话需要点击操作的启动使其变为RUNNING;若只想运行一次,则点击操作的执行一次即可。

Shell脚本如下:

进行保存即可。

测试为使用xxl-job的Linux执行器通过Shell来执行kettle-job,以上是局部Shell脚本,完整脚本在下文

Windows执行器相关任务

同理,点击任务管理->新增,此处测试运行模式为GLUE(PowerShell)是否正常,点击保存。

同理,点击操作的GLUE IDE,进行编辑

再新增运行模式为GLUE(Python)任务,点击保存。

同理,点击操作的GLUE IDE,进行编辑

测试为使用xxl-job的Windows执行器通过PowerShell或Python来执行exe,以上是局部脚本,完整脚本在下文。

任务类型为GLUE(PowerShell)会存在中文乱码情况:执行程式路径若存在中文则会找不到,并且输出的内容也会乱码,故此处测试需将脚本改为纯英文;

任务类型为GLUE(Python)来解决中文乱码情况:执行程式路径若存在中文正常执行,并且输出的内容也正常显示。

调度日志

任务配置完成后,点击三个任务的操作->执行一次即可启动执行一次任务。启动后,点击调度日志即可查看任务执行结果。

Linux执行器任务调度日志

查看执行结果:

点击操作->执行日志查看具体日志:

kettle-job功能是往目标表插入数据,为测试xxl-job的失败重试机制,故该目标表进行删除,所以执行结果一定会失败,从而测试重试机制,如下重试了一次,同样失败。

现在恢复创建该目标表,再次点击执行一次任务,查看调度日志:

查看执行日志:

Windows执行器任务调度日志

查看执行结果:

执行该exe是会显示一个时间弹窗:

点击操作->执行日志查看具体日志:

同理查看运行模式为GLUE(Python)任务的执行日志:

使用Python来执行exe,能解决中文乱码问题

执行状态说明

在xxl-job中,判断任务执行是否成功的标准如下,故下文的所有脚本均可以针对该规则来实现失败重试机制。

shell 复制代码
# 0代表成功,非0代表失败,若失败会触发xxl-job的自动失败重试
exit 0

执行Kettle

执行作业脚本

shell 复制代码
#!/bin/bash
source /etc/profile 
KETTLE_HOME=/usr/local/kettle/data-integration
KETTLE_LOG=/usr/local/kettle/kettle_run_log
UPDATE=$(date "+%F-%H-%M-%S")
JOBNAME="job1"

# 定义完整的日志文件路径
LOG_FILE="$KETTLE_LOG/${UPDATE}_$JOBNAME.log"

# 确保日志目录存在
mkdir -p "$KETTLE_LOG"

# 执行 Kettle 作业并捕获退出码
# 注意:使用子shell来执行,这样可以捕获整个管道的退出状态
set -o pipefail  # 确保管道中任意命令失败都返回非0

# 执行 Kettle 并记录日志
bash "$KETTLE_HOME/kitchen.sh" \
  -rep=repo_ssh \
  -user=admin \
  -pass=admin \
  -dir=/ETL \
  -job="$JOBNAME" \
  -level=Detailed 2>&1 | tee "$LOG_FILE"

# 获取退出状态
EXIT_CODE=$?

echo "Kettle 退出代码: $EXIT_CODE"
echo "日志文件: $LOG_FILE"

# 检查日志中是否包含 ERROR(忽略大小写)
if grep -qi "ERROR" "$LOG_FILE"; then
    echo "⚠️ 警告:Kettle日志中发现 ERROR 关键字!"
	# 显示部分错误日志
    echo "=== 发现的错误日志片段 ==="
    grep -i "ERROR" "$LOG_FILE" | head -10
    exit 1
# 再检查退出代码,若不等于0则判定失败
elif [ $EXIT_CODE -ne 0 ]; then
    echo "❌ Kettle 执行失败,退出码: $EXIT_CODE"
    exit $EXIT_CODE
else
    echo "✅ 未发现 ERROR,任务成功"
    exit 0
fi

执行转换脚本

shell 复制代码
#!/bin/bash
source /etc/profile 
KETTLE_HOME=/usr/local/kettle/data-integration
KETTLE_LOG=/usr/local/kettle/kettle_run_log
UPDATE=$(date "+%F-%H-%M-%S")
TRANSNAME="trans1"

# 定义完整的日志文件路径
LOG_FILE="$KETTLE_LOG/${UPDATE}_$TRANSNAME.log"

# 确保日志目录存在
mkdir -p "$KETTLE_LOG"

# 执行 Kettle 作业并捕获退出码
# 注意:使用子shell来执行,这样可以捕获整个管道的退出状态
set -o pipefail  # 确保管道中任意命令失败都返回非0

# 执行 Kettle 并记录日志
bash "$KETTLE_HOME/pan.sh" \
  -rep=repo_ssh \
  -user=admin \
  -pass=admin \
  -dir=/ETL \
  -trans="$TRANSNAME" \
  -level=Detailed 2>&1 | tee "$LOG_FILE"

# 获取退出状态
EXIT_CODE=$?

echo "Kettle 退出代码: $EXIT_CODE"
echo "日志文件: $LOG_FILE"

# 检查日志中是否包含 ERROR(忽略大小写)
if grep -qi "ERROR" "$LOG_FILE"; then
    echo "⚠️ 警告:Kettle日志中发现 ERROR 关键字!"
	# 显示部分错误日志
    echo "=== 发现的错误日志片段 ==="
    grep -i "ERROR" "$LOG_FILE" | head -10
    exit 1
# 再检查退出代码,若不等于0则判定失败
elif [ $EXIT_CODE -ne 0 ]; then
    echo "❌ Kettle 执行失败,退出码: $EXIT_CODE"
    exit $EXIT_CODE
else
    echo "✅ 未发现 ERROR,任务成功"
    exit 0
fi

执行EXE脚本

使用PowerShell

因为xxl-job执行Powershell脚本会导致中文乱码,故目前修改为全英文。

Powershell脚本:

powershell 复制代码
# PowerShell script for XXL-Job

# Change to $true if administrator privileges are required
$UseAdmin = $false

$exePath = "C:\Users\Aiw\Desktop\py-exe\dist\time_popup2.exe"

# Check if the executable file exists
if (!(Test-Path $exePath)) {
    Write-Output "Error: Program file not found"
    exit 1
}

try {
    if ($UseAdmin) {
        Write-Output "Executing with administrator privileges..."
        $process = Start-Process powershell.exe -ArgumentList "-Command", "Start-Process '$exePath' -Wait; exit `$LASTEXITCODE" -Verb RunAs -Wait -PassThru
    } else {
        Write-Output "Executing with normal privileges..."
        $process = Start-Process -FilePath $exePath -Wait -PassThru -NoNewWindow
    }
    
    Write-Output "Execution completed, exit code: $($process.ExitCode)"
    exit $process.ExitCode
    
} catch {
    Write-Output "Execution failed: $_"
    exit 1
}

使用Pythhon

使用Python来解决xxl-job执行Powershell脚本导致中文乱码问题,支持中文路径并且中文输出。

python 复制代码
#!/usr/bin/env python3
import os
import subprocess
import sys

# 是否使用管理员权限
USE_ADMIN = False
# 执行的程式路径
EXE_PATH = r"C:\Users\Aiw\Desktop\py-exe中文路径测试\dist\time_popup2.exe"

# 设置输出编码为utf-8
sys.stdout.reconfigure(encoding='utf-8')

# 主逻辑
print(f"程式文件: {EXE_PATH}")

if not os.path.exists(EXE_PATH):
    print("错误: 程式文件不存在!")
    sys.exit(1)

try:
    if USE_ADMIN:
        print("使用管理员权限执行。")
        cmd = f'Start-Process "{EXE_PATH}" -Verb RunAs -Wait'
        result = subprocess.run(["powershell", "-Command", cmd], 
                               capture_output=True, text=True, encoding='gbk')
    else:
        print("使用普通权限执行。")
        result = subprocess.run([EXE_PATH], 
                               capture_output=True, text=True, encoding='gbk')
    
    print(f"执行完成,退出码: {result.returncode}")
    # 直接返回程序的退出码
    sys.exit(result.returncode)
    
except Exception as e:
    print(f"执行失败: {e}")
    sys.exit(1)
相关推荐
水天需0102 小时前
Grep 例程大全
linux
qq_229058012 小时前
运行djando项目 配置启动类 label_studio包含前后端启动方法
python·django
qq_251533592 小时前
查找 Python 中对象使用的内存量
开发语言·windows·python
CQ_YM2 小时前
Linux进程基础
linux·服务器·进程
yaoxin5211232 小时前
269. Java Stream API - Map-Filter-Reduce算法模型
java·python·算法
_OP_CHEN2 小时前
【Git原理与使用】(五)Git 多人协作:从分支协作到冲突解决,团队开发效率翻倍秘籍
linux·运维·git·团队开发·运维开发·企业级组件·git多人协作
JH灰色2 小时前
【大模型】-LangChain--Agent
windows·microsoft·langchain
梨落秋霜2 小时前
Python入门篇【函数】
开发语言·python
添砖java‘’3 小时前
常见的进程间通信方式详解
linux·c++·操作系统·信息与通信·进程通信