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

- 任务状态规范:新增任务默认停止状态,任务更新时保持任务状态不变;
pull/8/MERGE
xuxueli 6 years ago
parent df2b9f7e0c
commit f62a30a28b

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save