Procházet zdrojové kódy

- 任务状态优化,仅运行状态"NORMAL"任务关联至quartz,降低quartz底层数据存储与调度压力;

xuxueli před 6 roky
rodič
revize
f62a30a28b

+ 4 - 4
doc/XXL-JOB官方文档.md Zobrazit soubor

1331
 - 5、组件化优化,移除对 spring 的依赖:非spring应用选用 "XxlJobExecutor" 、spring应用选用 "XxlJobSpringExecutor" 作为执行器组件; 
1331
 - 5、组件化优化,移除对 spring 的依赖:非spring应用选用 "XxlJobExecutor" 、spring应用选用 "XxlJobSpringExecutor" 作为执行器组件; 
1332
 - 6、新增无框架执行器Sample示例项目 "xxl-job-executor-sample-frameless"。不依赖第三方框架,只需main方法即可启动运行执行器;
1332
 - 6、新增无框架执行器Sample示例项目 "xxl-job-executor-sample-frameless"。不依赖第三方框架,只需main方法即可启动运行执行器;
1333
 - 7、任务RollingLog展示逻辑优化,修复超时任务无法查看的问题;
1333
 - 7、任务RollingLog展示逻辑优化,修复超时任务无法查看的问题;
1334
-- 8、[迭代中]任务状态与quartz解耦,降低quartz调度压力,仅NORMAL状态任务绑定quartz
1335
-- 9、[迭代中]新增任务默认运行状态,任务更新时运行状态保持不变;
1334
+- 8、任务状态优化,仅运行状态"NORMAL"任务关联至quartz,降低quartz底层数据存储与调度压力
1335
+- 9、任务状态规范:新增任务默认停止状态,任务更新时保持任务状态不变;
1336
 - 10、[迭代中]原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可,可执行任意命令;
1336
 - 10、[迭代中]原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可,可执行任意命令;
1337
-- 11、[迭代中]cron在线生成工具,如 "cronboot/cron.qqe2";
1338
-- 12、[迭代中]docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
1337
+- 11、[迭代中]docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
1339
 
1338
 
1340
 
1339
 
1341
 ### TODO LIST
1340
 ### TODO LIST
1364
 - 23、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
1363
 - 23、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
1365
 - 24、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
1364
 - 24、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
1366
 - 25、SimpleTrigger 支持;
1365
 - 25、SimpleTrigger 支持;
1366
+- 26、cron在线生成工具,如 "cronboot/cron.qqe2";
1367
 
1367
 
1368
 
1368
 
1369
 ## 七、其他
1369
 ## 七、其他

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java Zobrazit soubor

76
 		return xxlJobService.remove(id);
76
 		return xxlJobService.remove(id);
77
 	}
77
 	}
78
 	
78
 	
79
-	@RequestMapping("/pause")
79
+	@RequestMapping("/stop")		// TODO, pause >> stop
80
 	@ResponseBody
80
 	@ResponseBody
81
 	public ReturnT<String> pause(int id) {
81
 	public ReturnT<String> pause(int id) {
82
-		return xxlJobService.pause(id);
82
+		return xxlJobService.stop(id);
83
 	}
83
 	}
84
 	
84
 	
85
-	@RequestMapping("/resume")
85
+	@RequestMapping("/start")		// TODO, resume >> start
86
 	@ResponseBody
86
 	@ResponseBody
87
-	public ReturnT<String> resume(int id) {
88
-		return xxlJobService.resume(id);
87
+	public ReturnT<String> start(int id) {
88
+		return xxlJobService.start(id);
89
 	}
89
 	}
90
 	
90
 	
91
 	@RequestMapping("/trigger")
91
 	@RequestMapping("/trigger")

+ 0 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java Zobrazit soubor

2
 
2
 
3
 import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
3
 import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
4
 import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
4
 import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
5
-import com.xxl.job.admin.core.util.I18nUtil;
6
 import org.quartz.JobExecutionContext;
5
 import org.quartz.JobExecutionContext;
7
 import org.quartz.JobExecutionException;
6
 import org.quartz.JobExecutionException;
8
 import org.quartz.JobKey;
7
 import org.quartz.JobKey;
28
 		Integer jobId = Integer.valueOf(jobKey.getName());
27
 		Integer jobId = Integer.valueOf(jobKey.getName());
29
 
28
 
30
 		// trigger
29
 		// trigger
31
-		//XxlJobTrigger.trigger(jobId);
32
 		JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
30
 		JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
33
 	}
31
 	}
34
 
32
 

+ 101 - 114
xxl-job-admin/src/main/java/com/xxl/job/admin/core/schedule/XxlJobDynamicScheduler.java Zobrazit soubor

30
 import javax.servlet.http.HttpServletResponse;
30
 import javax.servlet.http.HttpServletResponse;
31
 import java.io.IOException;
31
 import java.io.IOException;
32
 import java.util.Date;
32
 import java.util.Date;
33
-import java.util.HashSet;
34
 import java.util.concurrent.ConcurrentHashMap;
33
 import java.util.concurrent.ConcurrentHashMap;
35
 
34
 
36
 /**
35
 /**
93
         }
92
         }
94
     }
93
     }
95
 
94
 
95
+
96
     // ---------------------- admin rpc provider (no server version) ----------------------
96
     // ---------------------- admin rpc provider (no server version) ----------------------
97
     private static JettyServerHandler jettyServerHandler;
97
     private static JettyServerHandler jettyServerHandler;
98
     private void initRpcProvider(){
98
     private void initRpcProvider(){
137
         return executorBiz;
137
         return executorBiz;
138
     }
138
     }
139
 
139
 
140
+
140
     // ---------------------- schedule util ----------------------
141
     // ---------------------- schedule util ----------------------
141
 
142
 
142
     /**
143
     /**
145
      * @param jobInfo
146
      * @param jobInfo
146
      */
147
      */
147
 	public static void fillJobInfo(XxlJobInfo jobInfo) {
148
 	public static void fillJobInfo(XxlJobInfo jobInfo) {
148
-		// TriggerKey : name + group
149
+
149
         String group = String.valueOf(jobInfo.getJobGroup());
150
         String group = String.valueOf(jobInfo.getJobGroup());
150
         String name = String.valueOf(jobInfo.getId());
151
         String name = String.valueOf(jobInfo.getId());
151
-        TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
152
 
152
 
153
+        // trigger key
154
+        TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
153
         try {
155
         try {
154
-			Trigger trigger = scheduler.getTrigger(triggerKey);
155
 
156
 
156
-			TriggerState triggerState = scheduler.getTriggerState(triggerKey);
157
-			
158
-			// parse params
157
+            // trigger cron
158
+			Trigger trigger = scheduler.getTrigger(triggerKey);
159
 			if (trigger!=null && trigger instanceof CronTriggerImpl) {
159
 			if (trigger!=null && trigger instanceof CronTriggerImpl) {
160
 				String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
160
 				String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
161
 				jobInfo.setJobCron(cronExpression);
161
 				jobInfo.setJobCron(cronExpression);
162
 			}
162
 			}
163
 
163
 
164
-			//JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
165
-            //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
166
-            //String jobClass = jobDetail.getJobClass().getName();
167
-
164
+            // trigger state
165
+            TriggerState triggerState = scheduler.getTriggerState(triggerKey);
168
 			if (triggerState!=null) {
166
 			if (triggerState!=null) {
169
 				jobInfo.setJobStatus(triggerState.name());
167
 				jobInfo.setJobStatus(triggerState.name());
170
 			}
168
 			}
169
+
170
+            //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
171
+            //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
172
+            //String jobClass = jobDetail.getJobClass().getName();
171
 			
173
 			
172
 		} catch (SchedulerException e) {
174
 		} catch (SchedulerException e) {
173
 			logger.error(e.getMessage(), e);
175
 			logger.error(e.getMessage(), e);
174
 		}
176
 		}
175
 	}
177
 	}
176
-	
177
-    /**
178
-     * check if exists
179
-     *
180
-     * @param jobName
181
-     * @param jobGroup
182
-     * @return
183
-     * @throws SchedulerException
184
-     */
185
-	public static boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
186
-		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
187
-		return scheduler.checkExists(triggerKey);
188
-	}
178
+
189
 
179
 
190
     /**
180
     /**
191
-     * addJob
181
+     * add trigger + job
192
      *
182
      *
193
      * @param jobName
183
      * @param jobName
194
      * @param jobGroup
184
      * @param jobGroup
197
      * @throws SchedulerException
187
      * @throws SchedulerException
198
      */
188
      */
199
 	public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
189
 	public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
200
-    	// TriggerKey : name + group
190
+    	// 1、job key
201
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
191
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
202
         JobKey jobKey = new JobKey(jobName, jobGroup);
192
         JobKey jobKey = new JobKey(jobName, jobGroup);
203
-        
204
-        // TriggerKey valid if_exists
205
-        if (checkExists(jobName, jobGroup)) {
206
-            logger.info(">>>>>>>>> addJob fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
207
-            return false;
193
+
194
+        // 2、valid
195
+        if (scheduler.checkExists(triggerKey)) {
196
+            return true;    // PASS
208
         }
197
         }
209
-        
210
-        // CronTrigger : TriggerKey + cronExpression	// withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
211
-        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
198
+
199
+        // 3、corn trigger
200
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();   // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
212
         CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
201
         CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
213
 
202
 
214
-        // JobDetail : jobClass
203
+        // 4、job detail
215
 		Class<? extends Job> jobClass_ = RemoteHttpJobBean.class;   // Class.forName(jobInfo.getJobClass());
204
 		Class<? extends Job> jobClass_ = RemoteHttpJobBean.class;   // Class.forName(jobInfo.getJobClass());
216
-        
217
 		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
205
 		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
206
+
218
         /*if (jobInfo.getJobData()!=null) {
207
         /*if (jobInfo.getJobData()!=null) {
219
         	JobDataMap jobDataMap = jobDetail.getJobDataMap();
208
         	JobDataMap jobDataMap = jobDetail.getJobDataMap();
220
         	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	
209
         	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	
221
         	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
210
         	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
222
 		}*/
211
 		}*/
223
         
212
         
224
-        // schedule : jobDetail + cronTrigger
213
+        // 5、schedule job
225
         Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
214
         Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
226
 
215
 
227
         logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
216
         logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
228
         return true;
217
         return true;
229
     }
218
     }
230
-    
219
+
220
+
231
     /**
221
     /**
232
-     * rescheduleJob
222
+     * remove trigger + job
233
      *
223
      *
234
-     * @param jobGroup
235
      * @param jobName
224
      * @param jobName
236
-     * @param cronExpression
225
+     * @param jobGroup
237
      * @return
226
      * @return
238
      * @throws SchedulerException
227
      * @throws SchedulerException
239
      */
228
      */
240
-	public static boolean rescheduleJob(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
241
-    	
242
-    	// TriggerKey valid if_exists
243
-        if (!checkExists(jobName, jobGroup)) {
244
-        	logger.info(">>>>>>>>>>> rescheduleJob fail, job not exists, JobGroup:{}, JobName:{}", jobGroup, jobName);
245
-            return false;
246
-        }
247
-        
248
-        // TriggerKey : name + group
249
-        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
250
-        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
251
-
252
-        if (oldTrigger != null) {
253
-            // avoid repeat
254
-            String oldCron = oldTrigger.getCronExpression();
255
-            if (oldCron.equals(cronExpression)){
256
-                return true;
257
-            }
229
+    public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
258
 
230
 
259
-            // CronTrigger : TriggerKey + cronExpression
260
-            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
261
-            oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
231
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
262
 
232
 
263
-            // rescheduleJob
264
-            scheduler.rescheduleJob(triggerKey, oldTrigger);
265
-        } else {
266
-            // CronTrigger : TriggerKey + cronExpression
267
-            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
268
-            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
269
-
270
-            // JobDetail-JobDataMap fresh
271
-            JobKey jobKey = new JobKey(jobName, jobGroup);
272
-            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
273
-            /*JobDataMap jobDataMap = jobDetail.getJobDataMap();
274
-            jobDataMap.clear();
275
-            jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));*/
276
-
277
-            // Trigger fresh
278
-            HashSet<Trigger> triggerSet = new HashSet<Trigger>();
279
-            triggerSet.add(cronTrigger);
280
-
281
-            scheduler.scheduleJob(jobDetail, triggerSet, true);
233
+        if (scheduler.checkExists(triggerKey)) {
234
+            scheduler.unscheduleJob(triggerKey);    // trigger + job
282
         }
235
         }
283
 
236
 
284
-        logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
237
+        logger.info(">>>>>>>>>>> removeJob success, triggerKey:{}", triggerKey);
285
         return true;
238
         return true;
286
     }
239
     }
287
-    
240
+
241
+
288
     /**
242
     /**
289
-     * unscheduleJob
243
+     * updateJobCron
290
      *
244
      *
291
-     * @param jobName
292
      * @param jobGroup
245
      * @param jobGroup
246
+     * @param jobName
247
+     * @param cronExpression
293
      * @return
248
      * @return
294
      * @throws SchedulerException
249
      * @throws SchedulerException
295
      */
250
      */
296
-    public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
297
-    	// TriggerKey : name + group
251
+	public static boolean updateJobCron(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
252
+
253
+        // 1、job key
298
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
254
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
299
-        boolean result = false;
300
-        if (checkExists(jobName, jobGroup)) {
301
-            result = scheduler.unscheduleJob(triggerKey);
302
-            logger.info(">>>>>>>>>>> removeJob, triggerKey:{}, result [{}]", triggerKey, result);
255
+
256
+        // 2、valid
257
+        if (!scheduler.checkExists(triggerKey)) {
258
+            return true;    // PASS
259
+        }
260
+
261
+        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
262
+
263
+        // 3、avoid repeat cron
264
+        String oldCron = oldTrigger.getCronExpression();
265
+        if (oldCron.equals(cronExpression)){
266
+            return true;    // PASS
303
         }
267
         }
268
+
269
+        // 4、new cron trigger
270
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
271
+        oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
272
+
273
+        // 5、rescheduleJob
274
+        scheduler.rescheduleJob(triggerKey, oldTrigger);
275
+
276
+        /*
277
+        JobKey jobKey = new JobKey(jobName, jobGroup);
278
+
279
+        // old job detail
280
+        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
281
+
282
+        // new trigger
283
+        HashSet<Trigger> triggerSet = new HashSet<Trigger>();
284
+        triggerSet.add(cronTrigger);
285
+        // cover trigger of job detail
286
+        scheduler.scheduleJob(jobDetail, triggerSet, true);*/
287
+
288
+        logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
304
         return true;
289
         return true;
305
     }
290
     }
306
 
291
 
292
+
307
     /**
293
     /**
308
      * pause
294
      * pause
309
      *
295
      *
312
      * @return
298
      * @return
313
      * @throws SchedulerException
299
      * @throws SchedulerException
314
      */
300
      */
315
-    public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
316
-    	// TriggerKey : name + group
301
+    /*public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
302
+
317
     	TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
303
     	TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
318
-        
304
+
319
         boolean result = false;
305
         boolean result = false;
320
-        if (checkExists(jobName, jobGroup)) {
306
+        if (scheduler.checkExists(triggerKey)) {
321
             scheduler.pauseTrigger(triggerKey);
307
             scheduler.pauseTrigger(triggerKey);
322
-            result = true;
323
-            logger.info(">>>>>>>>>>> pauseJob success, triggerKey:{}", triggerKey);
324
-        } else {
325
-        	logger.info(">>>>>>>>>>> pauseJob fail, triggerKey:{}", triggerKey);
308
+            result =  true;
326
         }
309
         }
310
+
311
+        logger.info(">>>>>>>>>>> pauseJob {}, triggerKey:{}", (result?"success":"fail"),triggerKey);
327
         return result;
312
         return result;
328
-    }
329
-    
313
+    }*/
314
+
315
+
330
     /**
316
     /**
331
      * resume
317
      * resume
332
      *
318
      *
335
      * @return
321
      * @return
336
      * @throws SchedulerException
322
      * @throws SchedulerException
337
      */
323
      */
338
-    public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
339
-    	// TriggerKey : name + group
340
-    	TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
324
+    /*public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
325
+
326
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
341
         
327
         
342
         boolean result = false;
328
         boolean result = false;
343
-        if (checkExists(jobName, jobGroup)) {
329
+        if (scheduler.checkExists(triggerKey)) {
344
             scheduler.resumeTrigger(triggerKey);
330
             scheduler.resumeTrigger(triggerKey);
345
             result = true;
331
             result = true;
346
-            logger.info(">>>>>>>>>>> resumeJob success, triggerKey:{}", triggerKey);
347
-        } else {
348
-        	logger.info(">>>>>>>>>>> resumeJob fail, triggerKey:{}", triggerKey);
349
         }
332
         }
333
+
334
+        logger.info(">>>>>>>>>>> resumeJob {}, triggerKey:{}", (result?"success":"fail"), triggerKey);
350
         return result;
335
         return result;
351
-    }
352
-    
336
+    }*/
337
+
338
+
353
     /**
339
     /**
354
      * run
340
      * run
355
      *
341
      *
358
      * @return
344
      * @return
359
      * @throws SchedulerException
345
      * @throws SchedulerException
360
      */
346
      */
361
-    public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
347
+    /*public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
362
     	// TriggerKey : name + group
348
     	// TriggerKey : name + group
363
     	JobKey jobKey = new JobKey(jobName, jobGroup);
349
     	JobKey jobKey = new JobKey(jobName, jobGroup);
364
-        
350
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
351
+
365
         boolean result = false;
352
         boolean result = false;
366
-        if (checkExists(jobName, jobGroup)) {
353
+        if (scheduler.checkExists(triggerKey)) {
367
             scheduler.triggerJob(jobKey);
354
             scheduler.triggerJob(jobKey);
368
             result = true;
355
             result = true;
369
             logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
356
             logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
371
         	logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
358
         	logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
372
         }
359
         }
373
         return result;
360
         return result;
374
-    }
361
+    }*/
375
 
362
 
376
 
363
 
377
     /**
364
     /**

+ 7 - 7
xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java Zobrazit soubor

28
 	public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime);
28
 	public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime);
29
 
29
 
30
 	/**
30
 	/**
31
-	 * add job
31
+	 * add job, default quartz stop
32
 	 *
32
 	 *
33
 	 * @param jobInfo
33
 	 * @param jobInfo
34
 	 * @return
34
 	 * @return
36
 	public ReturnT<String> add(XxlJobInfo jobInfo);
36
 	public ReturnT<String> add(XxlJobInfo jobInfo);
37
 
37
 
38
 	/**
38
 	/**
39
-	 * update job
39
+	 * update job, update quartz-cron if started
40
 	 *
40
 	 *
41
 	 * @param jobInfo
41
 	 * @param jobInfo
42
 	 * @return
42
 	 * @return
44
 	public ReturnT<String> update(XxlJobInfo jobInfo);
44
 	public ReturnT<String> update(XxlJobInfo jobInfo);
45
 
45
 
46
 	/**
46
 	/**
47
-	 * remove job
47
+	 * remove job, unbind quartz
48
 	 *
48
 	 *
49
 	 * @param id
49
 	 * @param id
50
 	 * @return
50
 	 * @return
52
 	public ReturnT<String> remove(int id);
52
 	public ReturnT<String> remove(int id);
53
 
53
 
54
 	/**
54
 	/**
55
-	 * pause job
55
+	 * start job, bind quartz
56
 	 *
56
 	 *
57
 	 * @param id
57
 	 * @param id
58
 	 * @return
58
 	 * @return
59
 	 */
59
 	 */
60
-	public ReturnT<String> pause(int id);
60
+	public ReturnT<String> start(int id);
61
 
61
 
62
 	/**
62
 	/**
63
-	 * resume job
63
+	 * stop job, unbind quartz
64
 	 *
64
 	 *
65
 	 * @param id
65
 	 * @param id
66
 	 * @return
66
 	 * @return
67
 	 */
67
 	 */
68
-	public ReturnT<String> resume(int id);
68
+	public ReturnT<String> stop(int id);
69
 
69
 
70
 	/**
70
 	/**
71
 	 * dashboard info
71
 	 * dashboard info

+ 21 - 31
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java Zobrazit soubor

124
 			return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
124
 			return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
125
 		}
125
 		}
126
 
126
 
127
-		// add in quartz
128
-        String qz_group = String.valueOf(jobInfo.getJobGroup());
129
-        String qz_name = String.valueOf(jobInfo.getId());
130
-        try {
131
-            XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron());
132
-            //XxlJobDynamicScheduler.pauseJob(qz_name, qz_group);
133
-            return new ReturnT<String>(qz_name);
134
-        } catch (SchedulerException e) {
135
-            logger.error(e.getMessage(), e);
136
-            try {
137
-                xxlJobInfoDao.delete(jobInfo.getId());
138
-                XxlJobDynamicScheduler.removeJob(qz_name, qz_group);
139
-            } catch (SchedulerException e1) {
140
-                logger.error(e.getMessage(), e1);
141
-            }
142
-            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage());
143
-        }
127
+		return new ReturnT<String>(String.valueOf(jobInfo.getId()));
144
 	}
128
 	}
145
 
129
 
146
 	@Override
130
 	@Override
201
 		exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
185
 		exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
202
         xxlJobInfoDao.update(exists_jobInfo);
186
         xxlJobInfoDao.update(exists_jobInfo);
203
 
187
 
204
-		// fresh quartz
188
+
189
+		// update quartz-cron if started
205
 		String qz_group = String.valueOf(exists_jobInfo.getJobGroup());
190
 		String qz_group = String.valueOf(exists_jobInfo.getJobGroup());
206
 		String qz_name = String.valueOf(exists_jobInfo.getId());
191
 		String qz_name = String.valueOf(exists_jobInfo.getId());
207
         try {
192
         try {
208
-            boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron());
209
-            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
193
+            XxlJobDynamicScheduler.updateJobCron(qz_group, qz_name, exists_jobInfo.getJobCron());
210
         } catch (SchedulerException e) {
194
         } catch (SchedulerException e) {
211
             logger.error(e.getMessage(), e);
195
             logger.error(e.getMessage(), e);
196
+			return ReturnT.FAIL;
212
         }
197
         }
213
 
198
 
214
-		return ReturnT.FAIL;
199
+		return ReturnT.SUCCESS;
215
 	}
200
 	}
216
 
201
 
217
 	@Override
202
 	@Override
221
         String name = String.valueOf(xxlJobInfo.getId());
206
         String name = String.valueOf(xxlJobInfo.getId());
222
 
207
 
223
 		try {
208
 		try {
209
+			// unbind quartz
224
 			XxlJobDynamicScheduler.removeJob(name, group);
210
 			XxlJobDynamicScheduler.removeJob(name, group);
211
+
225
 			xxlJobInfoDao.delete(id);
212
 			xxlJobInfoDao.delete(id);
226
 			xxlJobLogDao.delete(id);
213
 			xxlJobLogDao.delete(id);
227
 			xxlJobLogGlueDao.deleteByJobId(id);
214
 			xxlJobLogGlueDao.deleteByJobId(id);
228
 			return ReturnT.SUCCESS;
215
 			return ReturnT.SUCCESS;
229
 		} catch (SchedulerException e) {
216
 		} catch (SchedulerException e) {
230
 			logger.error(e.getMessage(), e);
217
 			logger.error(e.getMessage(), e);
218
+			return ReturnT.FAIL;
231
 		}
219
 		}
232
-		return ReturnT.FAIL;
220
+
233
 	}
221
 	}
234
 
222
 
235
 	@Override
223
 	@Override
236
-	public ReturnT<String> pause(int id) {
237
-        XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
238
-        String group = String.valueOf(xxlJobInfo.getJobGroup());
239
-        String name = String.valueOf(xxlJobInfo.getId());
224
+	public ReturnT<String> start(int id) {
225
+		XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
226
+		String group = String.valueOf(xxlJobInfo.getJobGroup());
227
+		String name = String.valueOf(xxlJobInfo.getId());
228
+		String cronExpression = xxlJobInfo.getJobCron();
240
 
229
 
241
 		try {
230
 		try {
242
-            boolean ret = XxlJobDynamicScheduler.pauseJob(name, group);	// jobStatus do not store
243
-            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
231
+			boolean ret = XxlJobDynamicScheduler.addJob(name, group, cronExpression);
232
+			return ret?ReturnT.SUCCESS:ReturnT.FAIL;
244
 		} catch (SchedulerException e) {
233
 		} catch (SchedulerException e) {
245
 			logger.error(e.getMessage(), e);
234
 			logger.error(e.getMessage(), e);
246
 			return ReturnT.FAIL;
235
 			return ReturnT.FAIL;
248
 	}
237
 	}
249
 
238
 
250
 	@Override
239
 	@Override
251
-	public ReturnT<String> resume(int id) {
240
+	public ReturnT<String> stop(int id) {
252
         XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
241
         XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
253
         String group = String.valueOf(xxlJobInfo.getJobGroup());
242
         String group = String.valueOf(xxlJobInfo.getJobGroup());
254
         String name = String.valueOf(xxlJobInfo.getId());
243
         String name = String.valueOf(xxlJobInfo.getId());
255
 
244
 
256
 		try {
245
 		try {
257
-			boolean ret = XxlJobDynamicScheduler.resumeJob(name, group);
258
-			return ret?ReturnT.SUCCESS:ReturnT.FAIL;
246
+			// bind quartz
247
+            boolean ret = XxlJobDynamicScheduler.removeJob(name, group);
248
+            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
259
 		} catch (SchedulerException e) {
249
 		} catch (SchedulerException e) {
260
 			logger.error(e.getMessage(), e);
250
 			logger.error(e.getMessage(), e);
261
 			return ReturnT.FAIL;
251
 			return ReturnT.FAIL;

+ 2 - 2
xxl-job-admin/src/main/resources/i18n/message.properties Zobrazit soubor

120
 jobinfo_script_location=脚本位置
120
 jobinfo_script_location=脚本位置
121
 jobinfo_shard_index=分片序号
121
 jobinfo_shard_index=分片序号
122
 jobinfo_shard_total=分片总数
122
 jobinfo_shard_total=分片总数
123
-jobinfo_opt_pause=
124
-jobinfo_opt_resume=恢复
123
+jobinfo_opt_stop=停
124
+jobinfo_opt_start=启动
125
 jobinfo_opt_log=日志
125
 jobinfo_opt_log=日志
126
 jobinfo_opt_run=执行
126
 jobinfo_opt_run=执行
127
 jobinfo_glue_remark=源码备注
127
 jobinfo_glue_remark=源码备注

+ 2 - 2
xxl-job-admin/src/main/resources/i18n/message_en.properties Zobrazit soubor

120
 jobinfo_script_location=Script location
120
 jobinfo_script_location=Script location
121
 jobinfo_shard_index=Shard index
121
 jobinfo_shard_index=Shard index
122
 jobinfo_shard_total=Shard total
122
 jobinfo_shard_total=Shard total
123
-jobinfo_opt_pause=Pause
124
-jobinfo_opt_resume=Resume
123
+jobinfo_opt_stop=Stop
124
+jobinfo_opt_start=Start
125
 jobinfo_opt_log=Log
125
 jobinfo_opt_log=Log
126
 jobinfo_opt_run=Run
126
 jobinfo_opt_run=Run
127
 jobinfo_glue_remark=Resource Remark
127
 jobinfo_glue_remark=Resource Remark

+ 27 - 17
xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js Zobrazit soubor

87
 						"width":'10%',
87
 						"width":'10%',
88
 	                	"visible" : true,
88
 	                	"visible" : true,
89
 	                	"render": function ( data, type, row ) {
89
 	                	"render": function ( data, type, row ) {
90
-	                		if ('NORMAL' == data) {
91
-	                			return '<small class="label label-success" ><i class="fa fa-clock-o"></i>'+ data +'</small>'; 
92
-							} else if ('PAUSED' == data){
93
-								return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
94
-							} else if ('BLOCKED' == data){
95
-								return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
90
+
91
+                            // status
92
+	                		if (data && data != 'NONE') {
93
+                                if ('NORMAL' == data) {
94
+                                    return '<small class="label label-success" ><i class="fa fa-clock-o"></i>RUNNING</small>';
95
+                                } else {
96
+                                    return '<small class="label label-warning" >ERROR('+ data +')</small>';
97
+                                }
98
+							} else {
99
+                                return '<small class="label label-default" ><i class="fa fa-clock-o"></i>STOP</small>';
96
 							}
100
 							}
101
+
97
 	                		return data;
102
 	                		return data;
98
 	                	}
103
 	                	}
99
 	                },
104
 	                },
103
 	                	"render": function ( data, type, row ) {
108
 	                	"render": function ( data, type, row ) {
104
 	                		return function(){
109
 	                		return function(){
105
 	                			// status
110
 	                			// status
106
-	                			var pause_resume = "";
107
-	                			if ('NORMAL' == row.jobStatus) {
108
-	                				pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_pause +'</button>  ';
109
-								} else if ('PAUSED' == row.jobStatus){
110
-									pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_resume +'</button>  ';
111
-								}
111
+	                			var start_stop = "";
112
+                                if (row.jobStatus && row.jobStatus != 'NONE') {
113
+                                    if ('NORMAL' == row.jobStatus) {
114
+                                        start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_stop +'</button>  ';
115
+                                    } else {
116
+                                        start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_stop +'</button>  ';
117
+                                    }
118
+                                } else {
119
+                                    start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_start +'</button>  ';
120
+                                }
121
+
112
 	                			// log url
122
 	                			// log url
113
 	                			var logUrl = base_url +'/joblog?jobId='+ row.id;
123
 	                			var logUrl = base_url +'/joblog?jobId='+ row.id;
114
 	                			
124
 	                			
123
                                 tableData['key'+row.id] = row;
133
                                 tableData['key'+row.id] = row;
124
 								var html = '<p id="'+ row.id +'" >'+
134
 								var html = '<p id="'+ row.id +'" >'+
125
 									'<button class="btn btn-primary btn-xs job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button>  '+
135
 									'<button class="btn btn-primary btn-xs job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button>  '+
126
-									pause_resume +
136
+                                    start_stop +
127
 									'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >'+ I18n.jobinfo_opt_log +'</button><br>  '+
137
 									'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >'+ I18n.jobinfo_opt_log +'</button><br>  '+
128
 									'<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button>  '+
138
 									'<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button>  '+
129
 									codeBtn +
139
 									codeBtn +
184
 
194
 
185
 		var type = $(this).attr("_type");
195
 		var type = $(this).attr("_type");
186
 		if ("job_pause" == type) {
196
 		if ("job_pause" == type) {
187
-			typeName = I18n.jobinfo_opt_pause ;
188
-			url = base_url + "/jobinfo/pause";
197
+			typeName = I18n.jobinfo_opt_stop ;
198
+			url = base_url + "/jobinfo/stop";
189
 			needFresh = true;
199
 			needFresh = true;
190
 		} else if ("job_resume" == type) {
200
 		} else if ("job_resume" == type) {
191
-			typeName = I18n.jobinfo_opt_resume ;
192
-			url = base_url + "/jobinfo/resume";
201
+			typeName = I18n.jobinfo_opt_start ;
202
+			url = base_url + "/jobinfo/start";
193
 			needFresh = true;
203
 			needFresh = true;
194
 		} else if ("job_del" == type) {
204
 		} else if ("job_del" == type) {
195
 			typeName = I18n.system_opt_del ;
205
 			typeName = I18n.system_opt_del ;