XXL-JOB 源码改造实战

背景

在日常使用 XXL-JOB 的过程中,运维和开发人员经常会遇到这样的需求:

在任务管理页面,希望能够不局限于某个执行器,而是一次性查看所有执行器下的任务情况。

然而,XXL-JOB 默认的实现是必须选择具体的执行器,才能筛选对应的任务。这在一些运维场景下显得不太方便。

如图所示:

43bb7b70bb7b91977a533982dea9079a

因此我在项目中基于xxl-job-2.4.0对xxl-job-admin源码做了一些改造,实现了执行器“全部查询” 的功能,本文就来分享一下具体的改造思路。

一、问题分析

XXL-JOB 任务管理页面的查询逻辑中,前端会将选中的 jobGroup(执行器 ID)传到后端,后端再通过 SQL 条件查询对应的任务:

1
AND t.job_group = #{jobGroup}

问题是,这样的写法导致必须指定某个执行器,否则查询不到任务。
因此我们需要 在下拉框中增加“全部”选项,并在 SQL 查询时做特殊处理

二、SQL 改造

xxl-job-adminJobInfoDao.xml 中,找到任务分页查询方法 pageList,原来的 SQL 条件大概是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<if test="triggerStatus gte 0">
AND t.trigger_status = #{triggerStatus}
</if>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
ORDER BY id DESC
LIMIT #{offset}, #{pagesize}
</select>

image-20250901101938032

这里我做了一个小改动:

  • jobGroup = 0 时,认为是“全部”,不拼接 job_group 条件;
  • 否则,按正常逻辑过滤。

完整 SQL 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup != null and jobGroup != 0">
AND t.job_group = #{jobGroup}
</if>
<if test="triggerStatus gte 0">
AND t.trigger_status = #{triggerStatus}
</if>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
ORDER BY id DESC
LIMIT #{offset}, #{pagesize}
</select>

这样,就实现了 可选全部任务组 的功能。

三、前端改造

接着我们需要在前端(任务管理页面)增加“全部”选项。

修改 jobinfo.index.ftl 中的下拉框代码:

1
2
3
4
5
6
7
8
9
10
<div class="col-xs-3">
<div class="input-group">
<span class="input-group-addon">${I18n.jobinfo_field_jobgroup}</span>
<select class="form-control" id="jobGroup" >
<#list JobGroupList as group>
<option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option>
</#list>
</select>
</div>
</div>

修改后:

image-20250901102429148

效果如下图:

xxljob 全部执行器

可以看到,在执行器下拉框里已经多了一个 “全部” 的选项。

四、效果验证

  • 选择具体执行器:依旧按原有逻辑,只查询对应执行器的任务;
  • 选择 全部:SQL 不拼接 job_group 条件,返回所有执行器下的任务。

这样一来,任务查询更加灵活,运维人员在排查问题时可以一眼看到所有任务,非常方便。

五、总结

通过这次源码小改造,实现了 XXL-JOB 任务管理页面 “支持全部执行器查询” 的功能。
关键点主要有两个:

  1. SQL 层:增加 jobGroup=0 时跳过过滤条件;
  2. 前端层:在下拉框中增加一个“全部”选项。

这个改造点虽然不大,但极大提升了任务管理的效率,也算是一个比较实用的小优化。

如果你的团队也在使用 XXL-JOB,不妨尝试加上这个功能,相信会对日常运维带来帮助 🚀。