提交 f62a30a2 authored 作者: xuxueli's avatar xuxueli

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

- 任务状态规范:新增任务默认停止状态,任务更新时保持任务状态不变;
上级 df2b9f7e
......@@ -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";
## 七、其他
......
......@@ -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")
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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;
......
......@@ -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=源码备注
......
......@@ -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
......
......@@ -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 ;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论