|
@@ -25,6 +25,8 @@ public class JobScheduleHelper {
|
25
|
25
|
return instance;
|
26
|
26
|
}
|
27
|
27
|
|
|
28
|
+ public static final long PRE_READ_MS = 5000; // pre read
|
|
29
|
+
|
28
|
30
|
private Thread scheduleThread;
|
29
|
31
|
private Thread ringThread;
|
30
|
32
|
private volatile boolean scheduleThreadToStop = false;
|
|
@@ -47,11 +49,11 @@ public class JobScheduleHelper {
|
47
|
49
|
}
|
48
|
50
|
logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
|
49
|
51
|
|
|
52
|
+ Connection conn = null;
|
50
|
53
|
while (!scheduleThreadToStop) {
|
51
|
54
|
|
52
|
55
|
// 扫描任务
|
53
|
56
|
long start = System.currentTimeMillis();
|
54
|
|
- Connection conn = null;
|
55
|
57
|
PreparedStatement preparedStatement = null;
|
56
|
58
|
try {
|
57
|
59
|
if (conn==null || conn.isClosed()) {
|
|
@@ -65,16 +67,16 @@ public class JobScheduleHelper {
|
65
|
67
|
// tx start
|
66
|
68
|
|
67
|
69
|
// 1、预读5s内调度任务
|
68
|
|
- long maxNextTime = System.currentTimeMillis() + 5000;
|
69
|
|
- List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(maxNextTime);
|
|
70
|
+ List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(System.currentTimeMillis() + PRE_READ_MS);
|
70
|
71
|
if (scheduleList!=null && scheduleList.size()>0) {
|
71
|
72
|
// 2、推送时间轮
|
72
|
73
|
for (XxlJobInfo jobInfo: scheduleList) {
|
73
|
74
|
|
74
|
75
|
// 时间轮刻度计算
|
75
|
|
- if (System.currentTimeMillis() > jobInfo.getTriggerNextTime() + 5000) {
|
|
76
|
+ if (System.currentTimeMillis() > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
|
76
|
77
|
// 过期超5s:本地忽略,当前时间开始计算下次触发时间
|
77
|
78
|
|
|
79
|
+ // fresh next
|
78
|
80
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
79
|
81
|
jobInfo.setTriggerNextTime(
|
80
|
82
|
new CronExpression(jobInfo.getJobCron())
|
|
@@ -82,44 +84,55 @@ public class JobScheduleHelper {
|
82
|
84
|
.getTime()
|
83
|
85
|
);
|
84
|
86
|
|
85
|
|
- // pass
|
86
|
|
- continue;
|
87
|
|
-
|
88
|
87
|
} else if (System.currentTimeMillis() > jobInfo.getTriggerNextTime()) {
|
89
|
|
- // 过期5s内 :立即触发一次,当前时间开始计算下次触发时间
|
|
88
|
+ // 过期5s内 :立即触发一次,当前时间开始计算下次触发时间;一旦过期,预读一次;
|
90
|
89
|
|
91
|
|
- jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
92
|
|
- jobInfo.setTriggerNextTime(
|
93
|
|
- new CronExpression(jobInfo.getJobCron())
|
94
|
|
- .getNextValidTimeAfter(new Date())
|
95
|
|
- .getTime()
|
96
|
|
- );
|
|
90
|
+ CronExpression cronExpression = new CronExpression(jobInfo.getJobCron());
|
|
91
|
+ long nextTime = cronExpression.getNextValidTimeAfter(new Date()).getTime();
|
97
|
92
|
|
98
|
|
- // do trigger
|
|
93
|
+ // 1、trigger
|
99
|
94
|
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);
|
100
|
95
|
|
|
96
|
+ // 2、fresh next
|
|
97
|
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
98
|
+ jobInfo.setTriggerNextTime(nextTime);
|
|
99
|
+
|
|
100
|
+ // 3、check pre read
|
|
101
|
+ if (jobInfo.getTriggerNextTime() - System.currentTimeMillis() < PRE_READ_MS) {
|
|
102
|
+
|
|
103
|
+ // 1、make ring second
|
|
104
|
+ int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
|
105
|
+
|
|
106
|
+ // 2、push time ring
|
|
107
|
+ pushTimeRing(ringSecond, jobInfo.getId());
|
|
108
|
+
|
|
109
|
+ // 3、fresh next
|
|
110
|
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
111
|
+ jobInfo.setTriggerNextTime(
|
|
112
|
+ new CronExpression(jobInfo.getJobCron())
|
|
113
|
+ .getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
|
114
|
+ .getTime()
|
|
115
|
+ );
|
|
116
|
+
|
|
117
|
+ }
|
|
118
|
+
|
101
|
119
|
logger.debug(">>>>>>>>>>> xxl-job, push trigger : jobId = " + jobInfo.getId() );
|
102
|
120
|
} else {
|
103
|
121
|
// 未过期:正常触发,递增计算下次触发时间
|
104
|
122
|
|
|
123
|
+ // 1、make ring second
|
105
|
124
|
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
106
|
125
|
|
|
126
|
+ // 2、push time ring
|
|
127
|
+ pushTimeRing(ringSecond, jobInfo.getId());
|
|
128
|
+
|
|
129
|
+ // 3、fresh next
|
107
|
130
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
108
|
131
|
jobInfo.setTriggerNextTime(
|
109
|
132
|
new CronExpression(jobInfo.getJobCron())
|
110
|
133
|
.getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
111
|
134
|
.getTime()
|
112
|
135
|
);
|
113
|
|
-
|
114
|
|
- // push async ring
|
115
|
|
- List<Integer> ringItemData = ringData.get(ringSecond);
|
116
|
|
- if (ringItemData == null) {
|
117
|
|
- ringItemData = new ArrayList<Integer>();
|
118
|
|
- ringData.put(ringSecond, ringItemData);
|
119
|
|
- }
|
120
|
|
- ringItemData.add(jobInfo.getId());
|
121
|
|
-
|
122
|
|
- logger.debug(">>>>>>>>>>> xxl-job, push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) );
|
123
|
136
|
}
|
124
|
137
|
|
125
|
138
|
}
|
|
@@ -139,12 +152,6 @@ public class JobScheduleHelper {
|
139
|
152
|
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e);
|
140
|
153
|
}
|
141
|
154
|
} finally {
|
142
|
|
- if (conn != null) {
|
143
|
|
- try {
|
144
|
|
- conn.close();
|
145
|
|
- } catch (SQLException e) {
|
146
|
|
- }
|
147
|
|
- }
|
148
|
155
|
if (null != preparedStatement) {
|
149
|
156
|
try {
|
150
|
157
|
preparedStatement.close();
|
|
@@ -166,6 +173,12 @@ public class JobScheduleHelper {
|
166
|
173
|
}
|
167
|
174
|
|
168
|
175
|
}
|
|
176
|
+ if (conn != null) {
|
|
177
|
+ try {
|
|
178
|
+ conn.close();
|
|
179
|
+ } catch (SQLException e) {
|
|
180
|
+ }
|
|
181
|
+ }
|
169
|
182
|
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");
|
170
|
183
|
}
|
171
|
184
|
});
|
|
@@ -235,6 +248,18 @@ public class JobScheduleHelper {
|
235
|
248
|
ringThread.start();
|
236
|
249
|
}
|
237
|
250
|
|
|
251
|
+ private void pushTimeRing(int ringSecond, int jobId){
|
|
252
|
+ // push async ring
|
|
253
|
+ List<Integer> ringItemData = ringData.get(ringSecond);
|
|
254
|
+ if (ringItemData == null) {
|
|
255
|
+ ringItemData = new ArrayList<Integer>();
|
|
256
|
+ ringData.put(ringSecond, ringItemData);
|
|
257
|
+ }
|
|
258
|
+ ringItemData.add(jobId);
|
|
259
|
+
|
|
260
|
+ logger.debug(">>>>>>>>>>> xxl-job, push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) );
|
|
261
|
+ }
|
|
262
|
+
|
238
|
263
|
public void toStop(){
|
239
|
264
|
|
240
|
265
|
// 1、stop schedule
|