Browse Source

任务触发时支持动态传参,调度中心与API服务均提供提供动态参数功能

xuxueli 7 năm trước cách đây
mục cha
commit
67fc5a1895

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

@@ -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、调度线程池改为协程方式实现,大幅降低系统内存消耗;
-- 21、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
+- 20、Release发布时,一同发布调度中心安装包,真正实现开箱即用;
 
 
 ## 七、其他
 ## 七、其他
 
 

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

@@ -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) {
-		JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null);
+	public ReturnT<String> triggerJob(int id, String executorParam) {
+		// force cover job param
+		if (executorParam == null) {
+			executorParam = "";
+		}
+
+		JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam);
 		return ReturnT.SUCCESS;
 		return ReturnT.SUCCESS;
 	}
 	}
 	
 	

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

@@ -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);
 	}
 	}
 
 
 }
 }

+ 1 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java

@@ -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);

+ 9 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java

@@ -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) {
-        helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam);
+    public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
+        helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
     }
     }
 
 
     public static void toStop() {
     public static void toStop() {

+ 9 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java

@@ -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());
 
 

+ 1 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java

@@ -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

+ 29 - 0
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl

@@ -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>

+ 45 - 4
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js

@@ -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');