任务触发时支持动态传参,调度中心与API服务均提供提供动态参数功能
This commit is contained in:
parent
dea702f60c
commit
67fc5a1895
|
@ -1283,7 +1283,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
||||||
- 33、修复表字段 “t.order”与数据库关键字冲突查询失败的问题,
|
- 33、修复表字段 “t.order”与数据库关键字冲突查询失败的问题,
|
||||||
- 34、调度中心提供API服务,支持通过API服务对任务进行查询、新增、更新、启停等操作;
|
- 34、调度中心提供API服务,支持通过API服务对任务进行查询、新增、更新、启停等操作;
|
||||||
- 35、分片任务失败重试优化,仅重试当前失败的分片;
|
- 35、分片任务失败重试优化,仅重试当前失败的分片;
|
||||||
- 36、任务参数数据框调整,手动触发时支持动态输入参数;
|
- 36、任务触发时支持动态传参,调度中心与API服务均提供提供动态参数功能;
|
||||||
|
|
||||||
|
|
||||||
### TODO LIST
|
### TODO LIST
|
||||||
|
@ -1298,7 +1298,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
||||||
- 9、执行器Log清理功能:调度中心Log删除时同步删除执行器中的Log文件;
|
- 9、执行器Log清理功能:调度中心Log删除时同步删除执行器中的Log文件;
|
||||||
- 10、Bean模式任务,JobHandler自动从执行器中查询展示为下拉框,选择后自动填充任务名称等属性;
|
- 10、Bean模式任务,JobHandler自动从执行器中查询展示为下拉框,选择后自动填充任务名称等属性;
|
||||||
- 11、API事件触发类型任务(更类似MQ消息)支持"动态传参、延时消费";该类型任务不走Quartz,单独建立MQ消息表,调度中心竞争触发;待定,该功能与 XXL-MQ 冲突,该场景建议用后者;
|
- 11、API事件触发类型任务(更类似MQ消息)支持"动态传参、延时消费";该类型任务不走Quartz,单独建立MQ消息表,调度中心竞争触发;待定,该功能与 XXL-MQ 冲突,该场景建议用后者;
|
||||||
- 12、API任务触发时支持动态传参;
|
- 12、调度线程池改为协程方式实现,大幅降低系统内存消耗;
|
||||||
- 13、任务依赖增强,新增任务类型 "流程任务",流程节点可挂载普通类型任务,承担任务依赖功能。现有子任务模型取消;需要考虑任务依赖死循环问题;
|
- 13、任务依赖增强,新增任务类型 "流程任务",流程节点可挂载普通类型任务,承担任务依赖功能。现有子任务模型取消;需要考虑任务依赖死循环问题;
|
||||||
- 14、任务告警逻辑调整:任务调度,以及任务回调失败时,均推送监控队列。后期考虑通过任务Log字段控制告警状态;
|
- 14、任务告警逻辑调整:任务调度,以及任务回调失败时,均推送监控队列。后期考虑通过任务Log字段控制告警状态;
|
||||||
- 15、新增任务默认运行状态,任务更新时运行状态保持不变;
|
- 15、新增任务默认运行状态,任务更新时运行状态保持不变;
|
||||||
|
@ -1306,8 +1306,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
||||||
- 17、注册中心支持扩展,除默认基于DB之外,支持扩展接入第三方注册中心如zk、eureka等;
|
- 17、注册中心支持扩展,除默认基于DB之外,支持扩展接入第三方注册中心如zk、eureka等;
|
||||||
- 18、流程任务,支持参数传递;
|
- 18、流程任务,支持参数传递;
|
||||||
- 19、SimpleTrigger 支持;
|
- 19、SimpleTrigger 支持;
|
||||||
- 20、调度线程池改为协程方式实现,大幅降低系统内存消耗;
|
- 20、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
|
||||||
- 21、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
|
|
||||||
|
|
||||||
## 七、其他
|
## 七、其他
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,13 @@ public class JobInfoController {
|
||||||
@RequestMapping("/trigger")
|
@RequestMapping("/trigger")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
//@PermessionLimit(limit = false)
|
//@PermessionLimit(limit = false)
|
||||||
public ReturnT<String> triggerJob(int id) {
|
public ReturnT<String> triggerJob(int id, String executorParam) {
|
||||||
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null);
|
// force cover job param
|
||||||
|
if (executorParam == null) {
|
||||||
|
executorParam = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam);
|
||||||
return ReturnT.SUCCESS;
|
return ReturnT.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class RemoteHttpJobBean extends QuartzJobBean {
|
||||||
|
|
||||||
// trigger
|
// trigger
|
||||||
//XxlJobTrigger.trigger(jobId);
|
//XxlJobTrigger.trigger(jobId);
|
||||||
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null);
|
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -73,7 +73,7 @@ public class JobFailMonitorHelper {
|
||||||
XxlJobInfo info = XxlJobDynamicScheduler.xxlJobInfoDao.loadById(log.getJobId());
|
XxlJobInfo info = XxlJobDynamicScheduler.xxlJobInfoDao.loadById(log.getJobId());
|
||||||
|
|
||||||
if (log.getExecutorFailRetryCount() > 0) {
|
if (log.getExecutorFailRetryCount() > 0) {
|
||||||
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam());
|
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), null);
|
||||||
String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>";
|
String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>";
|
||||||
log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
|
log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
|
||||||
XxlJobDynamicScheduler.xxlJobLogDao.updateTriggerInfo(log);
|
XxlJobDynamicScheduler.xxlJobLogDao.updateTriggerInfo(log);
|
||||||
|
|
|
@ -29,11 +29,11 @@ public class JobTriggerPoolHelper {
|
||||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
|
||||||
|
|
||||||
public void addTrigger(final int jobId, final TriggerTypeEnum triggerType, final int failRetryCount, final String executorShardingParam) {
|
public void addTrigger(final int jobId, final TriggerTypeEnum triggerType, final int failRetryCount, final String executorShardingParam, final String executorParam) {
|
||||||
triggerPool.execute(new Runnable() {
|
triggerPool.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam);
|
XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,17 @@ public class JobTriggerPoolHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param jobId
|
* @param jobId
|
||||||
|
* @param triggerType
|
||||||
* @param failRetryCount
|
* @param failRetryCount
|
||||||
* >=0: use this param
|
* >=0: use this param
|
||||||
* <0: use param from job info config
|
* <0: use param from job info config
|
||||||
*
|
* @param executorShardingParam
|
||||||
|
* @param executorParam
|
||||||
|
* null: use job param
|
||||||
|
* not null: cover job param
|
||||||
*/
|
*/
|
||||||
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam) {
|
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
|
||||||
helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam);
|
helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void toStop() {
|
public static void toStop() {
|
||||||
|
|
|
@ -30,18 +30,25 @@ public class XxlJobTrigger {
|
||||||
* trigger job
|
* trigger job
|
||||||
*
|
*
|
||||||
* @param jobId
|
* @param jobId
|
||||||
|
* @param triggerType
|
||||||
* @param failRetryCount
|
* @param failRetryCount
|
||||||
* >=0: use this param
|
* >=0: use this param
|
||||||
* <0: use param from job info config
|
* <0: use param from job info config
|
||||||
*
|
* @param executorShardingParam
|
||||||
|
* @param executorParam
|
||||||
|
* null: use job param
|
||||||
|
* not null: cover job param
|
||||||
*/
|
*/
|
||||||
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam) {
|
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
|
||||||
// load data
|
// load data
|
||||||
XxlJobInfo jobInfo = XxlJobDynamicScheduler.xxlJobInfoDao.loadById(jobId);
|
XxlJobInfo jobInfo = XxlJobDynamicScheduler.xxlJobInfoDao.loadById(jobId);
|
||||||
if (jobInfo == null) {
|
if (jobInfo == null) {
|
||||||
logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId);
|
logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (executorParam != null) {
|
||||||
|
jobInfo.setExecutorParam(executorParam);
|
||||||
|
}
|
||||||
int finalFailRetryCount = failRetryCount>=0?failRetryCount:jobInfo.getExecutorFailRetryCount();
|
int finalFailRetryCount = failRetryCount>=0?failRetryCount:jobInfo.getExecutorFailRetryCount();
|
||||||
XxlJobGroup group = XxlJobDynamicScheduler.xxlJobGroupDao.load(jobInfo.getJobGroup());
|
XxlJobGroup group = XxlJobDynamicScheduler.xxlJobGroupDao.load(jobInfo.getJobGroup());
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class AdminBizImpl implements AdminBiz {
|
||||||
int childJobId = (StringUtils.isNotBlank(childJobIds[i]) && StringUtils.isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
|
int childJobId = (StringUtils.isNotBlank(childJobIds[i]) && StringUtils.isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
|
||||||
if (childJobId > 0) {
|
if (childJobId > 0) {
|
||||||
|
|
||||||
JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, 0, null);
|
JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, 0, null, null);
|
||||||
ReturnT<String> triggerChildResult = ReturnT.SUCCESS;
|
ReturnT<String> triggerChildResult = ReturnT.SUCCESS;
|
||||||
|
|
||||||
// add msg
|
// add msg
|
||||||
|
|
|
@ -380,6 +380,35 @@ exit 0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<#-- trigger -->
|
||||||
|
<div class="modal fade" id="jobTriggerModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog ">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" >${I18n.jobinfo_opt_run}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="form-horizontal form" role="form" >
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<textarea class="textarea form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" style="height: 63px; line-height: 1.2;"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-6">
|
||||||
|
<button type="button" class="btn btn-primary ok" >${I18n.system_save}</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">${I18n.system_cancel}</button>
|
||||||
|
<input type="hidden" name="id" >
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<@netCommon.commonScript />
|
<@netCommon.commonScript />
|
||||||
<!-- DataTables -->
|
<!-- DataTables -->
|
||||||
<script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script>
|
||||||
|
|
|
@ -122,7 +122,7 @@ $(function() {
|
||||||
// html
|
// html
|
||||||
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_operate" _type="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 +
|
pause_resume +
|
||||||
'<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> '+
|
||||||
|
@ -195,9 +195,6 @@ $(function() {
|
||||||
typeName = I18n.system_opt_del ;
|
typeName = I18n.system_opt_del ;
|
||||||
url = base_url + "/jobinfo/remove";
|
url = base_url + "/jobinfo/remove";
|
||||||
needFresh = true;
|
needFresh = true;
|
||||||
} else if ("job_trigger" == type) {
|
|
||||||
typeName = I18n.jobinfo_opt_run ;
|
|
||||||
url = base_url + "/jobinfo/trigger";
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +243,50 @@ $(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// job trigger
|
||||||
|
$("#job_list").on('click', '.job_trigger',function() {
|
||||||
|
var id = $(this).parent('p').attr("id");
|
||||||
|
var row = tableData['key'+id];
|
||||||
|
|
||||||
|
$("#jobTriggerModal .form input[name='id']").val( row.id );
|
||||||
|
$("#jobTriggerModal .form textarea[name='executorParam']").val( row.executorParam );
|
||||||
|
|
||||||
|
$('#jobTriggerModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||||
|
});
|
||||||
|
$("#jobTriggerModal .ok").on('click',function() {
|
||||||
|
$.ajax({
|
||||||
|
type : 'POST',
|
||||||
|
url : base_url + "/jobinfo/trigger",
|
||||||
|
data : {
|
||||||
|
"id" : $("#jobTriggerModal .form input[name='id']").val(),
|
||||||
|
"executorParam" : $("#jobTriggerModal .textarea[name='executorParam']").val()
|
||||||
|
},
|
||||||
|
dataType : "json",
|
||||||
|
success : function(data){
|
||||||
|
if (data.code == 200) {
|
||||||
|
$('#jobTriggerModal').modal('hide');
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
title: I18n.system_tips,
|
||||||
|
btn: [ I18n.system_ok ],
|
||||||
|
content: I18n.jobinfo_opt_run + I18n.system_success ,
|
||||||
|
icon: '1'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
layer.open({
|
||||||
|
title: I18n.system_tips,
|
||||||
|
btn: [ I18n.system_ok ],
|
||||||
|
content: (data.msg || I18n.jobinfo_opt_run + I18n.system_fail ),
|
||||||
|
icon: '2'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#jobTriggerModal").on('hide.bs.modal', function () {
|
||||||
|
$("#jobTriggerModal .form")[0].reset();
|
||||||
|
});
|
||||||
|
|
||||||
// add
|
// add
|
||||||
$(".add").click(function(){
|
$(".add").click(function(){
|
||||||
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||||
|
|
Loading…
Reference in New Issue