Browse Source

- 任务状态优化,仅运行状态"NORMAL"任务关联至quartz,降低quartz底层数据存储与调度压力;
- 任务状态规范:新增任务默认停止状态,任务更新时保持任务状态不变;

xuxueli 6 years ago
parent
commit
f62a30a28b

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

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

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

@@ -76,16 +76,16 @@ public class JobInfoController {
 		return xxlJobService.remove(id);
 	}
 	
-	@RequestMapping("/pause")
+	@RequestMapping("/stop")		// TODO, pause >> stop
 	@ResponseBody
 	public ReturnT<String> pause(int id) {
-		return xxlJobService.pause(id);
+		return xxlJobService.stop(id);
 	}
 	
-	@RequestMapping("/resume")
+	@RequestMapping("/start")		// TODO, resume >> start
 	@ResponseBody
-	public ReturnT<String> resume(int id) {
-		return xxlJobService.resume(id);
+	public ReturnT<String> start(int id) {
+		return xxlJobService.start(id);
 	}
 	
 	@RequestMapping("/trigger")

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

@@ -2,7 +2,6 @@ package com.xxl.job.admin.core.jobbean;
 
 import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
 import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
-import com.xxl.job.admin.core.util.I18nUtil;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.quartz.JobKey;
@@ -28,7 +27,6 @@ public class RemoteHttpJobBean extends QuartzJobBean {
 		Integer jobId = Integer.valueOf(jobKey.getName());
 
 		// trigger
-		//XxlJobTrigger.trigger(jobId);
 		JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
 	}
 

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

@@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -93,6 +92,7 @@ public final class XxlJobDynamicScheduler {
         }
     }
 
+
     // ---------------------- admin rpc provider (no server version) ----------------------
     private static JettyServerHandler jettyServerHandler;
     private void initRpcProvider(){
@@ -137,6 +137,7 @@ public final class XxlJobDynamicScheduler {
         return executorBiz;
     }
 
+
     // ---------------------- schedule util ----------------------
 
     /**
@@ -145,50 +146,39 @@ public final class XxlJobDynamicScheduler {
      * @param jobInfo
      */
 	public static void fillJobInfo(XxlJobInfo jobInfo) {
-		// TriggerKey : name + group
+
         String group = String.valueOf(jobInfo.getJobGroup());
         String name = String.valueOf(jobInfo.getId());
-        TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
 
+        // trigger key
+        TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
         try {
-			Trigger trigger = scheduler.getTrigger(triggerKey);
 
-			TriggerState triggerState = scheduler.getTriggerState(triggerKey);
-			
-			// parse params
+            // trigger cron
+			Trigger trigger = scheduler.getTrigger(triggerKey);
 			if (trigger!=null && trigger instanceof CronTriggerImpl) {
 				String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
 				jobInfo.setJobCron(cronExpression);
 			}
 
-			//JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
-            //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
-            //String jobClass = jobDetail.getJobClass().getName();
-
+            // trigger state
+            TriggerState triggerState = scheduler.getTriggerState(triggerKey);
 			if (triggerState!=null) {
 				jobInfo.setJobStatus(triggerState.name());
 			}
+
+            //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
+            //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
+            //String jobClass = jobDetail.getJobClass().getName();
 			
 		} catch (SchedulerException e) {
 			logger.error(e.getMessage(), e);
 		}
 	}
-	
-    /**
-     * check if exists
-     *
-     * @param jobName
-     * @param jobGroup
-     * @return
-     * @throws SchedulerException
-     */
-	public static boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
-		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
-		return scheduler.checkExists(triggerKey);
-	}
+
 
     /**
-     * addJob
+     * add trigger + job
      *
      * @param jobName
      * @param jobGroup
@@ -197,113 +187,109 @@ public final class XxlJobDynamicScheduler {
      * @throws SchedulerException
      */
 	public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
-    	// TriggerKey : name + group
+    	// 1、job key
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
         JobKey jobKey = new JobKey(jobName, jobGroup);
-        
-        // TriggerKey valid if_exists
-        if (checkExists(jobName, jobGroup)) {
-            logger.info(">>>>>>>>> addJob fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
-            return false;
+
+        // 2、valid
+        if (scheduler.checkExists(triggerKey)) {
+            return true;    // PASS
         }
-        
-        // CronTrigger : TriggerKey + cronExpression	// withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
-        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
+
+        // 3、corn trigger
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();   // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
         CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
 
-        // JobDetail : jobClass
+        // 4、job detail
 		Class<? extends Job> jobClass_ = RemoteHttpJobBean.class;   // Class.forName(jobInfo.getJobClass());
-        
 		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
+
         /*if (jobInfo.getJobData()!=null) {
         	JobDataMap jobDataMap = jobDetail.getJobDataMap();
         	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	
         	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
 		}*/
         
-        // schedule : jobDetail + cronTrigger
+        // 5、schedule job
         Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
 
         logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
         return true;
     }
-    
+
+
     /**
-     * rescheduleJob
+     * remove trigger + job
      *
-     * @param jobGroup
      * @param jobName
-     * @param cronExpression
+     * @param jobGroup
      * @return
      * @throws SchedulerException
      */
-	public static boolean rescheduleJob(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
-    	
-    	// TriggerKey valid if_exists
-        if (!checkExists(jobName, jobGroup)) {
-        	logger.info(">>>>>>>>>>> rescheduleJob fail, job not exists, JobGroup:{}, JobName:{}", jobGroup, jobName);
-            return false;
-        }
-        
-        // TriggerKey : name + group
-        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
-        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
-
-        if (oldTrigger != null) {
-            // avoid repeat
-            String oldCron = oldTrigger.getCronExpression();
-            if (oldCron.equals(cronExpression)){
-                return true;
-            }
+    public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
 
-            // CronTrigger : TriggerKey + cronExpression
-            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
-            oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
 
-            // rescheduleJob
-            scheduler.rescheduleJob(triggerKey, oldTrigger);
-        } else {
-            // CronTrigger : TriggerKey + cronExpression
-            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
-            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
-
-            // JobDetail-JobDataMap fresh
-            JobKey jobKey = new JobKey(jobName, jobGroup);
-            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
-            /*JobDataMap jobDataMap = jobDetail.getJobDataMap();
-            jobDataMap.clear();
-            jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));*/
-
-            // Trigger fresh
-            HashSet<Trigger> triggerSet = new HashSet<Trigger>();
-            triggerSet.add(cronTrigger);
-
-            scheduler.scheduleJob(jobDetail, triggerSet, true);
+        if (scheduler.checkExists(triggerKey)) {
+            scheduler.unscheduleJob(triggerKey);    // trigger + job
         }
 
-        logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
+        logger.info(">>>>>>>>>>> removeJob success, triggerKey:{}", triggerKey);
         return true;
     }
-    
+
+
     /**
-     * unscheduleJob
+     * updateJobCron
      *
-     * @param jobName
      * @param jobGroup
+     * @param jobName
+     * @param cronExpression
      * @return
      * @throws SchedulerException
      */
-    public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
-    	// TriggerKey : name + group
+	public static boolean updateJobCron(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
+
+        // 1、job key
         TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
-        boolean result = false;
-        if (checkExists(jobName, jobGroup)) {
-            result = scheduler.unscheduleJob(triggerKey);
-            logger.info(">>>>>>>>>>> removeJob, triggerKey:{}, result [{}]", triggerKey, result);
+
+        // 2、valid
+        if (!scheduler.checkExists(triggerKey)) {
+            return true;    // PASS
+        }
+
+        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
+
+        // 3、avoid repeat cron
+        String oldCron = oldTrigger.getCronExpression();
+        if (oldCron.equals(cronExpression)){
+            return true;    // PASS
         }
+
+        // 4、new cron trigger
+        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
+        oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
+
+        // 5、rescheduleJob
+        scheduler.rescheduleJob(triggerKey, oldTrigger);
+
+        /*
+        JobKey jobKey = new JobKey(jobName, jobGroup);
+
+        // old job detail
+        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
+
+        // new trigger
+        HashSet<Trigger> triggerSet = new HashSet<Trigger>();
+        triggerSet.add(cronTrigger);
+        // cover trigger of job detail
+        scheduler.scheduleJob(jobDetail, triggerSet, true);*/
+
+        logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
         return true;
     }
 
+
     /**
      * pause
      *
@@ -312,21 +298,21 @@ public final class XxlJobDynamicScheduler {
      * @return
      * @throws SchedulerException
      */
-    public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
-    	// TriggerKey : name + group
+    /*public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
+
     	TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
-        
+
         boolean result = false;
-        if (checkExists(jobName, jobGroup)) {
+        if (scheduler.checkExists(triggerKey)) {
             scheduler.pauseTrigger(triggerKey);
-            result = true;
-            logger.info(">>>>>>>>>>> pauseJob success, triggerKey:{}", triggerKey);
-        } else {
-        	logger.info(">>>>>>>>>>> pauseJob fail, triggerKey:{}", triggerKey);
+            result =  true;
         }
+
+        logger.info(">>>>>>>>>>> pauseJob {}, triggerKey:{}", (result?"success":"fail"),triggerKey);
         return result;
-    }
-    
+    }*/
+
+
     /**
      * resume
      *
@@ -335,21 +321,21 @@ public final class XxlJobDynamicScheduler {
      * @return
      * @throws SchedulerException
      */
-    public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
-    	// TriggerKey : name + group
-    	TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
+    /*public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
+
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
         
         boolean result = false;
-        if (checkExists(jobName, jobGroup)) {
+        if (scheduler.checkExists(triggerKey)) {
             scheduler.resumeTrigger(triggerKey);
             result = true;
-            logger.info(">>>>>>>>>>> resumeJob success, triggerKey:{}", triggerKey);
-        } else {
-        	logger.info(">>>>>>>>>>> resumeJob fail, triggerKey:{}", triggerKey);
         }
+
+        logger.info(">>>>>>>>>>> resumeJob {}, triggerKey:{}", (result?"success":"fail"), triggerKey);
         return result;
-    }
-    
+    }*/
+
+
     /**
      * run
      *
@@ -358,12 +344,13 @@ public final class XxlJobDynamicScheduler {
      * @return
      * @throws SchedulerException
      */
-    public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
+    /*public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
     	// TriggerKey : name + group
     	JobKey jobKey = new JobKey(jobName, jobGroup);
-        
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
+
         boolean result = false;
-        if (checkExists(jobName, jobGroup)) {
+        if (scheduler.checkExists(triggerKey)) {
             scheduler.triggerJob(jobKey);
             result = true;
             logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
@@ -371,7 +358,7 @@ public final class XxlJobDynamicScheduler {
         	logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
         }
         return result;
-    }
+    }*/
 
 
     /**

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

@@ -28,7 +28,7 @@ public interface XxlJobService {
 	public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime);
 
 	/**
-	 * add job
+	 * add job, default quartz stop
 	 *
 	 * @param jobInfo
 	 * @return
@@ -36,7 +36,7 @@ public interface XxlJobService {
 	public ReturnT<String> add(XxlJobInfo jobInfo);
 
 	/**
-	 * update job
+	 * update job, update quartz-cron if started
 	 *
 	 * @param jobInfo
 	 * @return
@@ -44,7 +44,7 @@ public interface XxlJobService {
 	public ReturnT<String> update(XxlJobInfo jobInfo);
 
 	/**
-	 * remove job
+	 * remove job, unbind quartz
 	 *
 	 * @param id
 	 * @return
@@ -52,20 +52,20 @@ public interface XxlJobService {
 	public ReturnT<String> remove(int id);
 
 	/**
-	 * pause job
+	 * start job, bind quartz
 	 *
 	 * @param id
 	 * @return
 	 */
-	public ReturnT<String> pause(int id);
+	public ReturnT<String> start(int id);
 
 	/**
-	 * resume job
+	 * stop job, unbind quartz
 	 *
 	 * @param id
 	 * @return
 	 */
-	public ReturnT<String> resume(int id);
+	public ReturnT<String> stop(int id);
 
 	/**
 	 * dashboard info

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

@@ -124,23 +124,7 @@ public class XxlJobServiceImpl implements XxlJobService {
 			return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
 		}
 
-		// add in quartz
-        String qz_group = String.valueOf(jobInfo.getJobGroup());
-        String qz_name = String.valueOf(jobInfo.getId());
-        try {
-            XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron());
-            //XxlJobDynamicScheduler.pauseJob(qz_name, qz_group);
-            return new ReturnT<String>(qz_name);
-        } catch (SchedulerException e) {
-            logger.error(e.getMessage(), e);
-            try {
-                xxlJobInfoDao.delete(jobInfo.getId());
-                XxlJobDynamicScheduler.removeJob(qz_name, qz_group);
-            } catch (SchedulerException e1) {
-                logger.error(e.getMessage(), e1);
-            }
-            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage());
-        }
+		return new ReturnT<String>(String.valueOf(jobInfo.getId()));
 	}
 
 	@Override
@@ -201,17 +185,18 @@ public class XxlJobServiceImpl implements XxlJobService {
 		exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
         xxlJobInfoDao.update(exists_jobInfo);
 
-		// fresh quartz
+
+		// update quartz-cron if started
 		String qz_group = String.valueOf(exists_jobInfo.getJobGroup());
 		String qz_name = String.valueOf(exists_jobInfo.getId());
         try {
-            boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron());
-            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
+            XxlJobDynamicScheduler.updateJobCron(qz_group, qz_name, exists_jobInfo.getJobCron());
         } catch (SchedulerException e) {
             logger.error(e.getMessage(), e);
+			return ReturnT.FAIL;
         }
 
-		return ReturnT.FAIL;
+		return ReturnT.SUCCESS;
 	}
 
 	@Override
@@ -221,26 +206,30 @@ public class XxlJobServiceImpl implements XxlJobService {
         String name = String.valueOf(xxlJobInfo.getId());
 
 		try {
+			// unbind quartz
 			XxlJobDynamicScheduler.removeJob(name, group);
+
 			xxlJobInfoDao.delete(id);
 			xxlJobLogDao.delete(id);
 			xxlJobLogGlueDao.deleteByJobId(id);
 			return ReturnT.SUCCESS;
 		} catch (SchedulerException e) {
 			logger.error(e.getMessage(), e);
+			return ReturnT.FAIL;
 		}
-		return ReturnT.FAIL;
+
 	}
 
 	@Override
-	public ReturnT<String> pause(int id) {
-        XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
-        String group = String.valueOf(xxlJobInfo.getJobGroup());
-        String name = String.valueOf(xxlJobInfo.getId());
+	public ReturnT<String> start(int id) {
+		XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
+		String group = String.valueOf(xxlJobInfo.getJobGroup());
+		String name = String.valueOf(xxlJobInfo.getId());
+		String cronExpression = xxlJobInfo.getJobCron();
 
 		try {
-            boolean ret = XxlJobDynamicScheduler.pauseJob(name, group);	// jobStatus do not store
-            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
+			boolean ret = XxlJobDynamicScheduler.addJob(name, group, cronExpression);
+			return ret?ReturnT.SUCCESS:ReturnT.FAIL;
 		} catch (SchedulerException e) {
 			logger.error(e.getMessage(), e);
 			return ReturnT.FAIL;
@@ -248,14 +237,15 @@ public class XxlJobServiceImpl implements XxlJobService {
 	}
 
 	@Override
-	public ReturnT<String> resume(int id) {
+	public ReturnT<String> stop(int id) {
         XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
         String group = String.valueOf(xxlJobInfo.getJobGroup());
         String name = String.valueOf(xxlJobInfo.getId());
 
 		try {
-			boolean ret = XxlJobDynamicScheduler.resumeJob(name, group);
-			return ret?ReturnT.SUCCESS:ReturnT.FAIL;
+			// bind quartz
+            boolean ret = XxlJobDynamicScheduler.removeJob(name, group);
+            return ret?ReturnT.SUCCESS:ReturnT.FAIL;
 		} catch (SchedulerException e) {
 			logger.error(e.getMessage(), e);
 			return ReturnT.FAIL;

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

@@ -120,8 +120,8 @@ jobinfo_field_executorFailRetryCount_placeholder=失败重试次数,大于零
 jobinfo_script_location=脚本位置
 jobinfo_shard_index=分片序号
 jobinfo_shard_total=分片总数
-jobinfo_opt_pause=
-jobinfo_opt_resume=恢复
+jobinfo_opt_stop=停
+jobinfo_opt_start=启动
 jobinfo_opt_log=日志
 jobinfo_opt_run=执行
 jobinfo_glue_remark=源码备注

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

@@ -120,8 +120,8 @@ jobinfo_field_executorFailRetryCount_placeholder=Fail Retry Count. effect if gre
 jobinfo_script_location=Script location
 jobinfo_shard_index=Shard index
 jobinfo_shard_total=Shard total
-jobinfo_opt_pause=Pause
-jobinfo_opt_resume=Resume
+jobinfo_opt_stop=Stop
+jobinfo_opt_start=Start
 jobinfo_opt_log=Log
 jobinfo_opt_run=Run
 jobinfo_glue_remark=Resource Remark

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

@@ -87,13 +87,18 @@ $(function() {
 						"width":'10%',
 	                	"visible" : true,
 	                	"render": function ( data, type, row ) {
-	                		if ('NORMAL' == data) {
-	                			return '<small class="label label-success" ><i class="fa fa-clock-o"></i>'+ data +'</small>'; 
-							} else if ('PAUSED' == data){
-								return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
-							} else if ('BLOCKED' == data){
-								return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
+
+                            // status
+	                		if (data && data != 'NONE') {
+                                if ('NORMAL' == data) {
+                                    return '<small class="label label-success" ><i class="fa fa-clock-o"></i>RUNNING</small>';
+                                } else {
+                                    return '<small class="label label-warning" >ERROR('+ data +')</small>';
+                                }
+							} else {
+                                return '<small class="label label-default" ><i class="fa fa-clock-o"></i>STOP</small>';
 							}
+
 	                		return data;
 	                	}
 	                },
@@ -103,12 +108,17 @@ $(function() {
 	                	"render": function ( data, type, row ) {
 	                		return function(){
 	                			// status
-	                			var pause_resume = "";
-	                			if ('NORMAL' == row.jobStatus) {
-	                				pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_pause +'</button>  ';
-								} else if ('PAUSED' == row.jobStatus){
-									pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_resume +'</button>  ';
-								}
+	                			var start_stop = "";
+                                if (row.jobStatus && row.jobStatus != 'NONE') {
+                                    if ('NORMAL' == row.jobStatus) {
+                                        start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_stop +'</button>  ';
+                                    } else {
+                                        start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_stop +'</button>  ';
+                                    }
+                                } else {
+                                    start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_start +'</button>  ';
+                                }
+
 	                			// log url
 	                			var logUrl = base_url +'/joblog?jobId='+ row.id;
 	                			
@@ -123,7 +133,7 @@ $(function() {
                                 tableData['key'+row.id] = row;
 								var html = '<p id="'+ row.id +'" >'+
 									'<button class="btn btn-primary btn-xs job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button>  '+
-									pause_resume +
+                                    start_stop +
 									'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >'+ I18n.jobinfo_opt_log +'</button><br>  '+
 									'<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button>  '+
 									codeBtn +
@@ -184,12 +194,12 @@ $(function() {
 
 		var type = $(this).attr("_type");
 		if ("job_pause" == type) {
-			typeName = I18n.jobinfo_opt_pause ;
-			url = base_url + "/jobinfo/pause";
+			typeName = I18n.jobinfo_opt_stop ;
+			url = base_url + "/jobinfo/stop";
 			needFresh = true;
 		} else if ("job_resume" == type) {
-			typeName = I18n.jobinfo_opt_resume ;
-			url = base_url + "/jobinfo/resume";
+			typeName = I18n.jobinfo_opt_start ;
+			url = base_url + "/jobinfo/start";
 			needFresh = true;
 		} else if ("job_del" == type) {
 			typeName = I18n.system_opt_del ;