|
@@ -1,8 +1,8 @@
|
1
|
1
|
package com.xxl.job.admin.core.thread;
|
2
|
2
|
|
3
|
3
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
4
|
|
-import com.xxl.job.admin.core.model.XxlJobInfo;
|
5
|
4
|
import com.xxl.job.admin.core.cron.CronExpression;
|
|
5
|
+import com.xxl.job.admin.core.model.XxlJobInfo;
|
6
|
6
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
7
|
7
|
import org.slf4j.Logger;
|
8
|
8
|
import org.slf4j.LoggerFactory;
|
|
@@ -58,7 +58,7 @@ public class JobScheduleHelper {
|
58
|
58
|
|
59
|
59
|
// tx start
|
60
|
60
|
|
61
|
|
- // 1、查询JOB:"下次调度30s内" ( ...... -5 ... now ...... +30 ...... )
|
|
61
|
+ // 1、查询JOB:"下次调度30s内"
|
62
|
62
|
long maxNextTime = System.currentTimeMillis() + 30000;
|
63
|
63
|
long nowTime = System.currentTimeMillis();
|
64
|
64
|
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(maxNextTime);
|
|
@@ -66,35 +66,53 @@ public class JobScheduleHelper {
|
66
|
66
|
// 2、推送时间轮
|
67
|
67
|
for (XxlJobInfo jobInfo: scheduleList) {
|
68
|
68
|
|
69
|
|
- // 过期策略:过期=更新下次触发时间为当前、过期是否5s内=立即出发,否则忽略;
|
70
|
|
- if (jobInfo.getTriggerNextTime() < nowTime) {
|
71
|
|
- jobInfo.setTriggerNextTime(nowTime);
|
72
|
|
- if (jobInfo.getTriggerNextTime() < nowTime-10000) {
|
73
|
|
- continue;
|
74
|
|
- }
|
|
69
|
+ // 时间轮刻度计算
|
|
70
|
+ int ringSecond = -1;
|
|
71
|
+ if (jobInfo.getTriggerNextTime() < nowTime - 10000) { // 过期超10s:本地忽略,当前时间开始计算下次触发时间
|
|
72
|
+ ringSecond = -1;
|
|
73
|
+
|
|
74
|
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
75
|
+ jobInfo.setTriggerNextTime(
|
|
76
|
+ new CronExpression(jobInfo.getJobCron())
|
|
77
|
+ .getNextValidTimeAfter(new Date())
|
|
78
|
+ .getTime()
|
|
79
|
+ );
|
|
80
|
+ } else if (jobInfo.getTriggerNextTime() < nowTime) { // 过期10s内:立即触发一次,当前时间开始计算下次触发时间
|
|
81
|
+ ringSecond = (int)((nowTime/1000)%60);
|
|
82
|
+
|
|
83
|
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
84
|
+ jobInfo.setTriggerNextTime(
|
|
85
|
+ new CronExpression(jobInfo.getJobCron())
|
|
86
|
+ .getNextValidTimeAfter(new Date())
|
|
87
|
+ .getTime()
|
|
88
|
+ );
|
|
89
|
+ } else { // 未过期:正常触发,递增计算下次触发时间
|
|
90
|
+ ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
|
91
|
+
|
|
92
|
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
93
|
+ jobInfo.setTriggerNextTime(
|
|
94
|
+ new CronExpression(jobInfo.getJobCron())
|
|
95
|
+ .getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
|
96
|
+ .getTime()
|
|
97
|
+ );
|
|
98
|
+ }
|
|
99
|
+ if (ringSecond == -1) {
|
|
100
|
+ continue;
|
75
|
101
|
}
|
76
|
102
|
|
77
|
103
|
// push async ring
|
78
|
|
- int second = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
79
|
|
- List<Integer> ringItemData = ringData.get(second);
|
|
104
|
+ List<Integer> ringItemData = ringData.get(ringSecond);
|
80
|
105
|
if (ringItemData == null) {
|
81
|
106
|
ringItemData = new ArrayList<Integer>();
|
82
|
|
- ringData.put(second, ringItemData);
|
|
107
|
+ ringData.put(ringSecond, ringItemData);
|
83
|
108
|
}
|
84
|
109
|
ringItemData.add(jobInfo.getId());
|
85
|
110
|
|
86
|
|
- logger.info(">>>>>>>>>>> xxl-job, push time-ring : " + second + " = " + Arrays.asList(ringItemData) );
|
|
111
|
+ logger.info(">>>>>>>>>>> xxl-job, push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) );
|
87
|
112
|
}
|
88
|
113
|
|
89
|
114
|
// 3、更新trigger信息
|
90
|
115
|
for (XxlJobInfo jobInfo: scheduleList) {
|
91
|
|
- // update
|
92
|
|
- jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
93
|
|
- jobInfo.setTriggerNextTime(
|
94
|
|
- new CronExpression(jobInfo.getJobCron())
|
95
|
|
- .getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
96
|
|
- .getTime()
|
97
|
|
- );
|
98
|
116
|
XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);
|
99
|
117
|
}
|
100
|
118
|
|
|
@@ -141,28 +159,22 @@ public class JobScheduleHelper {
|
141
|
159
|
List<Integer> ringItemData = new ArrayList<>();
|
142
|
160
|
int nowSecond = (int)((System.currentTimeMillis()/1000)%60); // 避免处理耗时太长,跨过刻度;
|
143
|
161
|
if (lastSecond == -1) {
|
144
|
|
- if (ringData.containsKey(nowSecond)) {
|
145
|
|
- List<Integer> tmpData = ringData.remove(nowSecond);
|
146
|
|
- if (tmpData != null) {
|
147
|
|
- ringItemData.addAll(tmpData);
|
148
|
|
- }
|
|
162
|
+ lastSecond = (nowSecond+59)%60;
|
|
163
|
+ }
|
|
164
|
+ for (int i = 1; i <=60; i++) {
|
|
165
|
+ int secondItem = (lastSecond+i)%60;
|
|
166
|
+
|
|
167
|
+ List<Integer> tmpData = ringData.remove(secondItem);
|
|
168
|
+ if (tmpData != null) {
|
|
169
|
+ ringItemData.addAll(tmpData);
|
149
|
170
|
}
|
150
|
|
- lastSecond = nowSecond;
|
151
|
|
- } else {
|
152
|
|
- for (int i = 1; i <=60; i++) {
|
153
|
|
- int secondItem = (lastSecond+i)%60;
|
154
|
|
-
|
155
|
|
- List<Integer> tmpData = ringData.remove(secondItem);
|
156
|
|
- if (tmpData != null) {
|
157
|
|
- ringItemData.addAll(tmpData);
|
158
|
|
- }
|
159
|
171
|
|
160
|
|
- if (secondItem == nowSecond) {
|
161
|
|
- break;
|
162
|
|
- }
|
|
172
|
+ if (secondItem == nowSecond) {
|
|
173
|
+ break;
|
163
|
174
|
}
|
164
|
|
- lastSecond = nowSecond;
|
165
|
175
|
}
|
|
176
|
+ lastSecond = nowSecond;
|
|
177
|
+
|
166
|
178
|
|
167
|
179
|
logger.info(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) );
|
168
|
180
|
if (ringItemData!=null && ringItemData.size()>0) {
|
|
@@ -171,7 +183,6 @@ public class JobScheduleHelper {
|
171
|
183
|
// do trigger
|
172
|
184
|
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
|
173
|
185
|
}
|
174
|
|
-
|
175
|
186
|
// clear
|
176
|
187
|
ringItemData.clear();
|
177
|
188
|
}
|