Skip to content

Commit 5319b5b

Browse files
Merge branch 'master' into master
2 parents 49c3261 + 80b2df7 commit 5319b5b

17 files changed

Lines changed: 147 additions & 71 deletions

File tree

doc/XXL-JOB官方文档.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,9 @@ xxl.job.i18n=zh_CN
929929
xxl.job.triggerpool.fast.max=300
930930
xxl.job.triggerpool.slow.max=200
931931
932+
### 调度触发后,批量更新任务批次数量【必填】
933+
xxl.job.schedule.batchsize=100
934+
932935
### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
933936
xxl.job.logretentiondays=30
934937
```
@@ -1273,7 +1276,7 @@ public void demoJobHandler() throws Exception {
12731276
{
12741277
"input": "{输入信息,必填信息}",
12751278
"prompt": "{模型prompt,可选信息}",
1276-
"model": "{模型实现,如qwen3:0.6b,可选信息}"
1279+
"model": "{模型实现,如qwen3.5:2b,可选信息}"
12771280
}
12781281
```
12791282
- b、difyWorkflowJobHandler:DifyWorkflow 任务,支持自定义inputs、user、baseUrl、apiKey 等输入信息,示例参数如下;
@@ -2785,10 +2788,15 @@ public void execute() {
27852788
- 10、【优化】统一项目依赖管理结构,依赖版本统一到父级pom提升可维护性;
27862789
27872790
### 7.44 版本 v3.4.0 Release Notes[ING]
2788-
- 1、【优化】父POM依赖配置优化,移除容易配置;合并PR-3926;
2789-
- 2、【调整】Docker基础镜像调整为eclipse-temurin;
2790-
- 3、【TODO】调度触发性能优化:调度触发后任务分批批量更新,提升调度性能;
2791-
- 4、【TODO】调度中心OpenAPI完善,提供任务管理能力;封装Agent Skill并推送ClawHub;
2791+
- 1、【新增】调度性能提升:任务触发后分批批量更新,高频调度场景可百倍降低SQL操作合并执行,提升调度性能;
2792+
(任务触发后批量更新配置“xxl.job.schedule.batchsize”)
2793+
- 2、【调整】固定频率调度策略调整,修复小概率下触发时间偏差问题;
2794+
- 3、【调整】Docker基础镜像调整为eclipse-temurin;
2795+
- 4、【优化】父POM依赖配置优化,移除容易配置;合并PR-3926;
2796+
- 5、【升级】升级多项maven依赖至较新版本;
2797+
- 6、【优化】调度日志优化:支持执行器维度查看调度日志;新增调度日志索引,提升查询效率;
2798+
(数据库新增索引脚本:``` create index I_jobgroup on xxl_job_log (job_group); ``` )
2799+
- 7、【TODO】调度中心OpenAPI完善,提供任务管理能力;封装Agent Skill并推送ClawHub;
27922800
27932801
27942802
### TODO LIST
@@ -2827,11 +2835,10 @@ public void execute() {
28272835
- 调度日志:全局配置:废弃; 新增“调度日志策略”:任务维度自定义,保留3天、7天、1个月、3个月、一年、永久;
28282836
- 执行日志:新增“执行RollingLog开关”:任务维度自定义,支持:RollingLog、普通日志(slf4j输出)、关闭(不输出);
28292837
- 21、AccessToken:废弃全局配置;支持在线管理,动态生成、动态启停;
2830-
- 22、任务执行后分批批量更新,提升调度性能;
2831-
- 23、任务管理OpenAPI;
2832-
- 24、调度中心启动参数线上配置:告警发送邮箱、Token,支持线上配置生效,修改不需重启机器;
2833-
- 25、执行器内嵌server切换tomcat,精简依赖;
2834-
- 26、日志策略新增:
2838+
- 22、任务管理OpenAPI;
2839+
- 23、调度中心启动参数线上配置:告警发送邮箱、Token,支持线上配置生效,修改不需重启机器;
2840+
- 24、执行器内嵌server切换tomcat,精简依赖;
2841+
- 25、日志策略新增:
28352842
- 调度日志策略:任务级设置,最少保留1天。
28362843
- 执行日志策略:可选 RollingLog、slf4jLog;
28372844
- 清理逻辑,性能重构。

doc/db/tables_xxl_job.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ CREATE TABLE `xxl_job_log`
100100
PRIMARY KEY (`id`),
101101
KEY `I_trigger_time` (`trigger_time`),
102102
KEY `I_handle_code` (`handle_code`),
103-
KEY `I_jobid_jobgroup` (`job_id`,`job_group`),
104-
KEY `I_job_id` (`job_id`)
103+
KEY `I_jobgroup` (`job_group`),
104+
KEY `I_jobid` (`job_id`)
105105
) ENGINE = InnoDB
106106
DEFAULT CHARSET = utf8mb4;
107107

@@ -161,7 +161,7 @@ VALUES (1, 1, '示例任务01', now(), now(), 'XXL', '', 'CRON', '0 0 0 * * ? *'
161161
'DO_NOTHING', 'FIRST', 'ollamaJobHandler', '{
162162
"input": "慢SQL问题分析思路",
163163
"prompt": "你是一个研发工程师,擅长解决技术类问题。",
164-
"model": "qwen3:0.6b"
164+
"model": "qwen3.5:2b"
165165
}', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化',
166166
now(), ''),
167167
(3, 2, 'Dify示例任务', now(), now(), 'XXL', '', 'NONE', '',

pom.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,29 @@
2525
<maven.compiler.target>17</maven.compiler.target>
2626
<maven.test.skip>true</maven.test.skip>
2727
<!-- plugin -->
28-
<maven-compiler-plugin.version>3.14.1</maven-compiler-plugin.version>
28+
<maven-compiler-plugin.version>3.15.0</maven-compiler-plugin.version>
2929
<maven-source-plugin.version>3.4.0</maven-source-plugin.version>
3030
<maven-javadoc-plugin.version>3.12.0</maven-javadoc-plugin.version>
3131
<maven-gpg-plugin.version>3.2.8</maven-gpg-plugin.version>
32-
<central-publishing-maven-plugin.version>0.9.0</central-publishing-maven-plugin.version>
32+
<central-publishing-maven-plugin.version>0.10.0</central-publishing-maven-plugin.version>
3333
<!-- base -->
3434
<slf4j-api.version>2.0.17</slf4j-api.version>
35-
<junit-jupiter.version>6.0.1</junit-jupiter.version>
35+
<junit-jupiter.version>6.0.3</junit-jupiter.version>
3636

3737
<!-- jakarta.annotation-api -->
3838
<jakarta.annotation-api.version>3.0.0</jakarta.annotation-api.version>
3939

4040
<!-- spring -->
41-
<spring-boot.version>4.0.1</spring-boot.version>
42-
<spring.version>7.0.2</spring.version>
41+
<spring-boot.version>4.0.5</spring-boot.version>
42+
<spring.version>7.0.6</spring.version>
4343
<!-- mybatis & db -->
4444
<mybatis-spring-boot-starter.version>4.0.1</mybatis-spring-boot-starter.version>
45-
<mysql-connector-j.version>9.5.0</mysql-connector-j.version>
45+
<mysql-connector-j.version>9.6.0</mysql-connector-j.version>
4646

4747
<!-- net -->
48-
<netty.version>4.2.9.Final</netty.version>
48+
<netty.version>4.2.12.Final</netty.version>
4949
<!-- groovy -->
50-
<groovy.version>5.0.3</groovy.version>
50+
<groovy.version>5.0.4</groovy.version>
5151

5252
<!-- xxl-sso -->
5353
<xxl-sso.version>2.3.2</xxl-sso.version>
@@ -57,9 +57,9 @@
5757
<gson.version>2.13.2</gson.version>
5858

5959
<!-- spring-ai -->
60-
<spring-ai.version>2.0.0-M1</spring-ai.version>
60+
<spring-ai.version>2.0.0-M4</spring-ai.version>
6161
<!-- dify -->
62-
<dify-java-client.version>1.2.3</dify-java-client.version>
62+
<dify-java-client.version>1.2.5</dify-java-client.version>
6363
</properties>
6464

6565
<dependencyManagement>

xxl-job-admin/src/main/java/com/xxl/job/admin/controller/biz/JobLogController.java

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public String index(HttpServletRequest request,
6262
@RequestParam(value = "jobGroup", required = false, defaultValue = "0") Integer jobGroup,
6363
@RequestParam(value = "jobId", required = false, defaultValue = "0") Integer jobId) {
6464

65+
// 1、init JobGroupList
6566
// find all jobGroup
6667
List<XxlJobGroup> jobGroupListTotal = xxlJobGroupMapper.findAll();
6768

@@ -70,44 +71,31 @@ public String index(HttpServletRequest request,
7071
if (CollectionTool.isEmpty(jobGroupList)) {
7172
throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
7273
}
74+
List<Integer> jobGroupIds = jobGroupList.stream().map(XxlJobGroup::getId).toList();
7375

74-
// parse jobGroup
76+
// 2、check jobId
7577
if (jobId > 0) {
76-
// assign jobId (+ jobGroup)
78+
// valid jobId
7779
XxlJobInfo jobInfo = xxlJobInfoMapper.loadById(jobId);
7880
if (jobInfo == null) {
79-
// jobId not exist, inteceptor
8081
throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid"));
8182
}
83+
// valid jobGroup
8284
jobGroup = jobInfo.getJobGroup();
83-
} else if (jobGroup > 0) {
84-
// assign jobGroup
85-
Integer finalJobGroup = jobGroup;
86-
if (CollectionTool.isEmpty(jobGroupListTotal.stream().filter(item -> item.getId() == finalJobGroup).toList())) {
87-
// jobGroup not exist, use first
88-
jobGroup = jobGroupList.get(0).getId();
89-
}
90-
jobId = 0;
91-
} else {
92-
// default first valid jobGroup
93-
jobGroup = jobGroupList.get(0).getId();
94-
jobId = 0;
9585
}
9686

97-
/*// valid permission
98-
JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);*/
87+
// 3、init jobGroup, default first 1
88+
if (!jobGroupIds.contains(jobGroup)) {
89+
jobGroup = jobGroupList.get(0).getId();
90+
}
9991

100-
// find jobList
92+
// 4、init jobInfoList
10193
List<XxlJobInfo> jobInfoList = xxlJobInfoMapper.getJobsByGroup(jobGroup);
94+
List<Integer> jobIds = jobInfoList.stream().map(XxlJobInfo::getId).toList();
10295

103-
// parse jobId
104-
if (CollectionTool.isEmpty(jobInfoList)) {
96+
// 5、init JobId, default 0
97+
if (!jobIds.contains(jobId)) {
10598
jobId = 0;
106-
} else {
107-
if (!jobInfoList.stream().map(XxlJobInfo::getId).toList().contains(jobId)) {
108-
// jobId not exist, use first
109-
jobId = jobInfoList.get(0).getId();
110-
}
11199
}
112100

113101
// write
@@ -133,9 +121,9 @@ public Response<PageModel<XxlJobLog>> pageList(HttpServletRequest request,
133121
JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);
134122

135123
// valid jobId
136-
if (jobId < 1) {
124+
/*if (jobId < 1) {
137125
return Response.ofFail(I18nUtil.getString("system_please_choose") + I18nUtil.getString("jobinfo_job"));
138-
}
126+
}*/
139127

140128
// parse param
141129
Date triggerTimeStart = null;

xxl-job-admin/src/main/java/com/xxl/job/admin/mapper/XxlJobInfoMapper.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,12 @@ public int pageListCount(@Param("offset") int offset,
6161
*/
6262
public int scheduleUpdate(XxlJobInfo xxlJobInfo);
6363

64+
/**
65+
* batch update job info
66+
*
67+
* @param jobInfoList
68+
* @return
69+
*/
70+
public int scheduleBatchUpdate(@Param("list") List<XxlJobInfo> jobInfoList);
6471

6572
}

xxl-job-admin/src/main/java/com/xxl/job/admin/scheduler/config/XxlJobAdminBootstrap.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ public static ExecutorBiz getExecutorBiz(String address) throws Exception {
181181
@Value("${xxl.job.triggerpool.slow.max}")
182182
private int triggerPoolSlowMax;
183183

184+
@Value("${xxl.job.schedule.batchsize}")
185+
private int scheduleBatchSize;
186+
184187
@Value("${xxl.job.logretentiondays}")
185188
private int logretentiondays;
186189

@@ -244,6 +247,13 @@ public int getTriggerPoolSlowMax() {
244247
return triggerPoolSlowMax;
245248
}
246249

250+
public int getScheduleBatchSize() {
251+
if (!(scheduleBatchSize >=50 && scheduleBatchSize <= 500)) {
252+
return 100;
253+
}
254+
return scheduleBatchSize;
255+
}
256+
247257
public int getLogretentiondays() {
248258
if (logretentiondays < 3) {
249259
return -1; // Limit greater than or equal to 3, otherwise close

xxl-job-admin/src/main/java/com/xxl/job/admin/scheduler/thread/JobScheduleHelper.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void run() {
5959
}
6060
logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
6161

62-
// pre-read count: treadpool-size * trigger-qps (each trigger cost 100ms, qps = 1000/100 = 100)
62+
// pre-read count: treadpool-size * 10 (trigger-qps: 1000ms / 100ms each trigger cost)
6363
int preReadCount = (XxlJobAdminBootstrap.getInstance().getTriggerPoolFastMax() + XxlJobAdminBootstrap.getInstance().getTriggerPoolSlowMax()) * 10;
6464

6565
// do schedule
@@ -138,8 +138,14 @@ public void run() {
138138
}
139139

140140
// 3、update trigger info
141-
for (XxlJobInfo jobInfo: scheduleList) {
141+
/*for (XxlJobInfo jobInfo: scheduleList) {
142142
XxlJobAdminBootstrap.getInstance().getXxlJobInfoMapper().scheduleUpdate(jobInfo);
143+
}*/
144+
int batchSize = XxlJobAdminBootstrap.getInstance().getScheduleBatchSize();
145+
List<List<XxlJobInfo>> scheduleListBatches = CollectionTool.split(scheduleList, batchSize);
146+
for (List<XxlJobInfo> scheduleListBatch : scheduleListBatches) {
147+
int totalAffected = XxlJobAdminBootstrap.getInstance().getXxlJobInfoMapper().scheduleBatchUpdate(scheduleListBatch);
148+
logger.debug(">>>>>>>>>>> xxl-job, JobScheduleHelper scheduleBatchUpdate records:" + totalAffected);
143149
}
144150

145151
} else {

xxl-job-admin/src/main/java/com/xxl/job/admin/scheduler/type/strategy/FixRateScheduleType.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@
22

33
import com.xxl.job.admin.model.XxlJobInfo;
44
import com.xxl.job.admin.scheduler.type.ScheduleType;
5+
import com.xxl.tool.core.DateTool;
56

67
import java.util.Date;
78

89
public class FixRateScheduleType extends ScheduleType {
910

1011
@Override
1112
public Date generateNextTriggerTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
13+
1214
// generate next trigger time, fix rate delay
13-
return new Date(fromTime.getTime() + Long.parseLong(jobInfo.getScheduleConf()) * 1000L);
15+
Date nextTriggerTime = new Date(fromTime.getTime() + Long.parseLong(jobInfo.getScheduleConf()) * 1000L);
16+
17+
// assign second:
18+
if (nextTriggerTime.getTime() % 1000 != 0) {
19+
nextTriggerTime = DateTool.addSeconds(DateTool.setMilliseconds(nextTriggerTime, 0), 1);
20+
}
21+
22+
return nextTriggerTime;
23+
1424
}
1525

1626
}

xxl-job-admin/src/main/resources/application.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ xxl.job.i18n=zh_CN
6464
xxl.job.triggerpool.fast.max=300
6565
xxl.job.triggerpool.slow.max=200
6666

67+
## xxl-job, schedule batch size
68+
xxl.job.schedule.batchsize=100
69+
6770
### xxl-job, log retention days
6871
xxl.job.logretentiondays=30
6972

xxl-job-admin/src/main/resources/mapper/XxlJobInfoMapper.xml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,34 +240,39 @@
240240
AND trigger_status = 1
241241
</update>
242242

243-
<!--int scheduleUpdateBatch(@Param("list") List<XxlJobInfo> jobs);
244-
<update id="scheduleUpdateBatch" parameterType="java.util.List">
243+
<update id="scheduleBatchUpdate" parameterType="java.util.List">
245244
UPDATE xxl_job_info
246245
SET
247246
trigger_last_time = CASE id
248-
<foreach collection="list" item="item">
247+
<foreach collection="list" item="item" separator=" ">
249248
WHEN #{item.id} THEN #{item.triggerLastTime}
250249
</foreach>
250+
ELSE trigger_last_time
251251
END,
252252
trigger_next_time = CASE id
253-
<foreach collection="list" item="item">
253+
<foreach collection="list" item="item" separator=" ">
254254
WHEN #{item.id} THEN #{item.triggerNextTime}
255255
</foreach>
256+
ELSE trigger_next_time
256257
END,
257258
trigger_status = CASE id
258-
<foreach collection="list" item="item">
259+
<foreach collection="list" item="item" separator=" ">
259260
WHEN #{item.id} THEN
260261
<choose>
261-
<when test="item.triggerStatus >= 0">#{item.triggerStatus}</when>
262-
<otherwise>trigger_status</otherwise> &lt;!&ndash; 保持原值 &ndash;&gt;
262+
<when test="item.triggerStatus gte 0">
263+
#{item.triggerStatus}
264+
</when>
265+
<otherwise>trigger_status</otherwise>
263266
</choose>
264267
</foreach>
268+
ELSE trigger_status
265269
END
266270
WHERE id IN
267271
<foreach collection="list" item="item" open="(" separator="," close=")">
268272
#{item.id}
269273
</foreach>
270274
AND trigger_status = 1
271-
</update>-->
275+
</update>
276+
272277

273278
</mapper>

0 commit comments

Comments
 (0)