Просмотр исходного кода

任务循环依赖问题修复,避免子任务与父任务重复导致的调度死循环;

xuxueli 8 лет назад
Родитель
Сommit
4ce20c1038

+ 7 - 5
doc/XXL-JOB官方文档.md Просмотреть файл

@@ -374,7 +374,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
374 374
         GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "python" 脚本;
375 375
         GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "nodejs" 脚本;
376 376
     - JobHandler:运行模式为 "BEAN模式" 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值;
377
-    - 子任务Key:每个任务都拥有一个唯一的任务Key(任务Key可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务Key所对应的任务的一次主动调度。
377
+    - 子任务:每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。
378 378
     - 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略;
379 379
         单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
380 380
         丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
@@ -699,7 +699,7 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
699 699
 #### 5.4.9 调度日志
700 700
 调度中心每次进行任务调度,都会记录一条任务日志,任务日志主要包括以下三部分内容:
701 701
 
702
-- 任务信息:包括“执行器地址”、“JobHandler”和“执行参数”等属性,点击JobKey可查看,根据这些参数,可以精确的定位任务执行的具体机器和任务代码;
702
+- 任务信息:包括“执行器地址”、“JobHandler”和“执行参数”等属性,点击任务ID按钮可查看,根据这些参数,可以精确的定位任务执行的具体机器和任务代码;
703 703
 - 调度信息:包括“调度时间”、“调度结果”和“调度日志”等,根据这些参数,可以了解“调度中心”发起调度请求时具体情况。
704 704
 - 执行信息:包括“执行时间”、“执行结果”和“执行日志”等,根据这些参数,可以了解在“执行器”端任务执行的具体情况;
705 705
 
@@ -716,9 +716,9 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
716 716
 - 执行日志:任务执行过程中,业务代码中打印的完整执行日志,见“4.7 查看执行日志”;
717 717
 
718 718
 #### 5.4.10 任务依赖
719
-原理:XXL-JOB中每个任务都对应有一个任务Key,同时,每个任务支持设置属性“子任务Key”,因此,通过“任务Key”可以匹配任务依赖关系。
719
+原理:XXL-JOB中每个任务都对应有一个任务ID,同时,每个任务支持设置属性“子任务ID”,因此,通过“任务ID”可以匹配任务依赖关系。
720 720
 
721
-当父任务执行结束并且执行成功时,将会根据“子任务Key”匹配子任务依赖,如果匹配到子任务,将会主动触发一次子任务的执行。
721
+当父任务执行结束并且执行成功时,将会根据“子任务ID”匹配子任务依赖,如果匹配到子任务,将会主动触发一次子任务的执行。
722 722
 
723 723
 在任务日志界面,点击任务的“执行备注”的“查看”按钮,可以看到匹配子任务以及触发子任务执行的日志信息,如无信息则表示未触发子任务执行,可参考下图。
724 724
 
@@ -1102,7 +1102,8 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1102 1102
 - 25、底层系统日志级别规范调整,清理遗留代码;
1103 1103
 - 26、建表SQL优化,支持同步创建制定编码的库和表;
1104 1104
 - 27、系统安全性优化,登陆Token写Cookie时进行MD5加密,同时Cookie启用HttpOnly;
1105
-
1105
+- 28、新增"任务ID"属性,移除"JobKey"属性,前者承担所有功能,方便后续增强任务依赖功能。
1106
+- 29、任务循环依赖问题修复,避免子任务与父任务重复导致的调度死循环;
1106 1107
 
1107 1108
 ### TODO LIST
1108 1109
 - 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
@@ -1118,6 +1119,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1118 1119
 - 11、执行器Log清理功能:调度中心Log删除时同步删除执行器中的Log文件;
1119 1120
 - 12、Bean模式任务,JobHandler自动从执行器中查询展示为下拉框,选择后自动填充任务名称等属性;
1120 1121
 - 13、API事件触发类型任务(更类似MQ消息)支持"动态传参、延时消费";该类型任务不走Quartz,单独建立MQ消息表,调度中心竞争触发;
1122
+- 14、任务依赖增强,新增任务类型 "流程任务",流程节点可挂载普通类型任务,承担任务依赖功能。现有子任务模型取消;需要考虑任务依赖死循环问题;
1121 1123
 
1122 1124
 
1123 1125
 ## 七、其他

+ 1 - 1
doc/db/tables_xxl_job.sql Просмотреть файл

@@ -167,7 +167,7 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` (
167 167
   `glue_source` text COMMENT 'GLUE源代码',
168 168
   `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
169 169
   `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
170
-  `child_jobkey` varchar(255) DEFAULT NULL COMMENT '子任务Key',
170
+  `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
171 171
   PRIMARY KEY (`id`)
172 172
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
173 173
 

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java Просмотреть файл

@@ -31,7 +31,7 @@ public class XxlJobInfo {
31 31
 	private String glueRemark;		// GLUE备注
32 32
 	private Date glueUpdatetime;	// GLUE更新时间
33 33
 
34
-	private String childJobKey;		// 子任务Key
34
+	private String childJobId;		// 子任务ID,多个逗号分隔
35 35
 	
36 36
 	// copy from quartz
37 37
 	private String jobStatus;		// 任务状态 【base on quartz】
@@ -172,12 +172,12 @@ public class XxlJobInfo {
172 172
 		this.glueUpdatetime = glueUpdatetime;
173 173
 	}
174 174
 
175
-	public String getChildJobKey() {
176
-		return childJobKey;
175
+	public String getChildJobId() {
176
+		return childJobId;
177 177
 	}
178 178
 
179
-	public void setChildJobKey(String childJobKey) {
180
-		this.childJobKey = childJobKey;
179
+	public void setChildJobId(String childJobId) {
180
+		this.childJobId = childJobId;
181 181
 	}
182 182
 
183 183
 	public String getJobStatus() {

+ 2 - 3
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java Просмотреть файл

@@ -4,7 +4,6 @@ import com.xxl.job.admin.core.model.XxlJobGroup;
4 4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5 5
 import com.xxl.job.admin.core.model.XxlJobLog;
6 6
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
7
-import com.xxl.job.admin.core.util.JobKeyUtil;
8 7
 import com.xxl.job.admin.core.util.MailUtil;
9 8
 import com.xxl.job.core.biz.model.ReturnT;
10 9
 import com.xxl.job.core.handler.IJobHandler;
@@ -125,7 +124,7 @@ public class JobFailMonitorHelper {
125 124
 			"   <thead style=\"font-weight: bold;color: #ffffff;background-color: #ff8c00;\" >" +
126 125
 			"      <tr>\n" +
127 126
 			"         <td>执行器</td>\n" +
128
-			"         <td>JobKey</td>\n" +
127
+			"         <td>任务ID</td>\n" +
129 128
 			"         <td>任务描述</td>\n" +
130 129
 			"         <td>告警类型</td>\n" +
131 130
 			"      </tr>\n" +
@@ -156,7 +155,7 @@ public class JobFailMonitorHelper {
156 155
 				XxlJobGroup group = XxlJobDynamicScheduler.xxlJobGroupDao.load(Integer.valueOf(info.getJobGroup()));
157 156
 
158 157
 				String title = "调度中心监控报警";
159
-				String content = MessageFormat.format(mailBodyTemplate, group!=null?group.getTitle():"null", JobKeyUtil.formatJobKey(info), info.getJobDesc());
158
+				String content = MessageFormat.format(mailBodyTemplate, group!=null?group.getTitle():"null", info.getId(), info.getJobDesc());
160 159
 
161 160
 				MailUtil.sendMail(email, title, content);
162 161
 			}

+ 0 - 44
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JobKeyUtil.java Просмотреть файл

@@ -1,44 +0,0 @@
1
-package com.xxl.job.admin.core.util;
2
-
3
-import com.xxl.job.admin.core.model.XxlJobInfo;
4
-import org.apache.commons.lang3.StringUtils;
5
-
6
-/**
7
- * job key util
8
- *
9
- * @author xuxueli 2017-12-22 18:48:45
10
- */
11
-public class JobKeyUtil {
12
-
13
-    /**
14
-     * format job key
15
-     *
16
-     * @param xxlJobInfo
17
-     * @return
18
-     */
19
-    public static String formatJobKey(XxlJobInfo xxlJobInfo){
20
-        return String.valueOf(xxlJobInfo.getJobGroup())
21
-                .concat("_").concat(String.valueOf(xxlJobInfo.getId()));
22
-    }
23
-
24
-    /**
25
-     * parse jobId from JobKey
26
-     *
27
-     * @param jobKey
28
-     * @return
29
-     */
30
-    public static int parseJobId(String jobKey){
31
-        if (jobKey!=null && jobKey.trim().length()>0) {
32
-            String[] jobKeyArr = jobKey.split("_");
33
-            if (jobKeyArr.length == 2) {
34
-                String jobIdStr = jobKeyArr[1];
35
-                if (StringUtils.isNotBlank(jobIdStr) && StringUtils.isNumeric(jobIdStr)) {
36
-                    int jobId = Integer.valueOf(jobIdStr);
37
-                    return jobId;
38
-                }
39
-            }
40
-        }
41
-        return -1;
42
-    }
43
-
44
-}

+ 8 - 13
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java Просмотреть файл

@@ -1,11 +1,7 @@
1 1
 package com.xxl.job.admin.service.impl;
2 2
 
3
-import com.xxl.job.admin.controller.JobApiController;
4 3
 import com.xxl.job.admin.core.model.XxlJobInfo;
5 4
 import com.xxl.job.admin.core.model.XxlJobLog;
6
-import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
7
-import com.xxl.job.admin.core.trigger.XxlJobTrigger;
8
-import com.xxl.job.admin.core.util.JobKeyUtil;
9 5
 import com.xxl.job.admin.dao.XxlJobInfoDao;
10 6
 import com.xxl.job.admin.dao.XxlJobLogDao;
11 7
 import com.xxl.job.admin.dao.XxlJobRegistryDao;
@@ -16,7 +12,6 @@ import com.xxl.job.core.biz.model.RegistryParam;
16 12
 import com.xxl.job.core.biz.model.ReturnT;
17 13
 import com.xxl.job.core.handler.IJobHandler;
18 14
 import org.apache.commons.lang3.StringUtils;
19
-import org.quartz.SchedulerException;
20 15
 import org.slf4j.Logger;
21 16
 import org.slf4j.LoggerFactory;
22 17
 import org.springframework.stereotype.Service;
@@ -68,21 +63,21 @@ public class AdminBizImpl implements AdminBiz {
68 63
         String callbackMsg = null;
69 64
         if (IJobHandler.SUCCESS.getCode() == handleCallbackParam.getExecuteResult().getCode()) {
70 65
             XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(log.getJobId());
71
-            if (xxlJobInfo!=null && StringUtils.isNotBlank(xxlJobInfo.getChildJobKey())) {
66
+            if (xxlJobInfo!=null && StringUtils.isNotBlank(xxlJobInfo.getChildJobId())) {
72 67
                 callbackMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发子任务<<<<<<<<<<< </span><br>";
73 68
 
74
-                String[] childJobKeys = xxlJobInfo.getChildJobKey().split(",");
75
-                for (int i = 0; i < childJobKeys.length; i++) {
76
-                    int childJobId = JobKeyUtil.parseJobId(childJobKeys[i]);
69
+                String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
70
+                for (int i = 0; i < childJobIds.length; i++) {
71
+                    int childJobId = (StringUtils.isNotBlank(childJobIds[i]) && StringUtils.isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
77 72
                     if (childJobId > 0) {
78 73
                         ReturnT<String> triggerChildResult = xxlJobService.triggerJob(childJobId);
79 74
 
80 75
                         // add msg
81
-                        callbackMsg += MessageFormat.format("{0}/{1} [JobKey={2}], 触发{3}, 触发备注: {4} <br>",
82
-                                (i+1), childJobKeys.length, childJobKeys[i], (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?"成功":"失败"), triggerChildResult.getMsg());
76
+                        callbackMsg += MessageFormat.format("{0}/{1} [任务ID={2}], 触发{3}, 触发备注: {4} <br>",
77
+                                (i+1), childJobIds.length, childJobIds[i], (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?"成功":"失败"), triggerChildResult.getMsg());
83 78
                     } else {
84
-                        callbackMsg += MessageFormat.format(" {0}/{1} [JobKey={2}], 触发失败, 触发备注: JobKey格式错误 <br>",
85
-                                (i+1), childJobKeys.length, childJobKeys[i]);
79
+                        callbackMsg += MessageFormat.format(" {0}/{1} [任务ID={2}], 触发失败, 触发备注: 任务ID格式错误 <br>",
80
+                                (i+1), childJobIds.length, childJobIds[i]);
86 81
                     }
87 82
                 }
88 83
 

+ 29 - 24
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java Просмотреть файл

@@ -5,7 +5,6 @@ import com.xxl.job.admin.core.model.XxlJobGroup;
5 5
 import com.xxl.job.admin.core.model.XxlJobInfo;
6 6
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
7 7
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
8
-import com.xxl.job.admin.core.util.JobKeyUtil;
9 8
 import com.xxl.job.admin.dao.XxlJobGroupDao;
10 9
 import com.xxl.job.admin.dao.XxlJobInfoDao;
11 10
 import com.xxl.job.admin.dao.XxlJobLogDao;
@@ -104,19 +103,20 @@ public class XxlJobServiceImpl implements XxlJobService {
104 103
 			jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
105 104
 		}
106 105
 
107
-		// childJobKey valid
108
-		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
109
-			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
110
-			for (String childJobKeyItem: childJobKeys) {
111
-				int childJobId = JobKeyUtil.parseJobId(childJobKeyItem);
112
-				if (childJobId <= 0) {
113
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
114
-				}
115
-				XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(childJobId);
116
-				if (childJobInfo==null) {
117
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
106
+		// ChildJobId valid
107
+		if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
108
+			String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
109
+			for (String childJobIdItem: childJobIds) {
110
+				if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
111
+					XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
112
+					if (childJobInfo==null) {
113
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})无效", childJobIdItem));
114
+					}
115
+				} else {
116
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})格式错误", childJobIdItem));
118 117
 				}
119 118
 			}
119
+			jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
120 120
 		}
121 121
 
122 122
 		// add in db
@@ -167,19 +167,24 @@ public class XxlJobServiceImpl implements XxlJobService {
167 167
 			return new ReturnT<String>(ReturnT.FAIL_CODE, "失败处理策略非法");
168 168
 		}
169 169
 
170
-		// childJobKey valid
171
-		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
172
-			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
173
-			for (String childJobKeyItem: childJobKeys) {
174
-				int childJobId = JobKeyUtil.parseJobId(childJobKeyItem);
175
-				if (childJobId <= 0) {
176
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
177
-				}
178
-                XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(childJobId);
179
-				if (childJobInfo==null) {
180
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
170
+		// ChildJobId valid
171
+		if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
172
+			String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
173
+			for (String childJobIdItem: childJobIds) {
174
+				if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
175
+					XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
176
+					if (childJobInfo==null) {
177
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})无效", childJobIdItem));
178
+					}
179
+					// avoid cycle relate
180
+					if (childJobInfo.getId() == jobInfo.getId()) {
181
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})不可与父任务重复", childJobIdItem));
182
+					}
183
+				} else {
184
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})格式错误", childJobIdItem));
181 185
 				}
182 186
 			}
187
+			jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
183 188
 		}
184 189
 
185 190
 		// stage job info
@@ -198,7 +203,7 @@ public class XxlJobServiceImpl implements XxlJobService {
198 203
 		exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
199 204
 		exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
200 205
 		exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy());
201
-		exists_jobInfo.setChildJobKey(jobInfo.getChildJobKey());
206
+		exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
202 207
         xxlJobInfoDao.update(exists_jobInfo);
203 208
 
204 209
 		// fresh quartz

+ 5 - 5
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml Просмотреть файл

@@ -27,7 +27,7 @@
27 27
 	    <result column="glue_remark" property="glueRemark" />
28 28
 		<result column="glue_updatetime" property="glueUpdatetime" />
29 29
 
30
-		<result column="child_jobkey" property="childJobKey" />
30
+		<result column="child_jobid" property="childJobId" />
31 31
 	</resultMap>
32 32
 
33 33
 	<sql id="Base_Column_List">
@@ -48,7 +48,7 @@
48 48
 		t.glue_source,
49 49
 		t.glue_remark,
50 50
 		t.glue_updatetime,
51
-		t.child_jobkey
51
+		t.child_jobid
52 52
 	</sql>
53 53
 	
54 54
 	<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
@@ -97,7 +97,7 @@
97 97
 			glue_source,
98 98
 			glue_remark,
99 99
 			glue_updatetime,
100
-			child_jobkey
100
+			child_jobid
101 101
 		) VALUES (
102 102
 			#{jobGroup},
103 103
 			#{jobCron}, 
@@ -115,7 +115,7 @@
115 115
 			#{glueSource},
116 116
 			#{glueRemark},
117 117
 			NOW(),
118
-			#{childJobKey}
118
+			#{childJobId}
119 119
 		);
120 120
 		<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
121 121
 			SELECT LAST_INSERT_ID()
@@ -146,7 +146,7 @@
146 146
 			glue_source = #{glueSource},
147 147
 			glue_remark = #{glueRemark},
148 148
 			glue_updatetime = #{glueUpdatetime},
149
-			child_jobkey = #{childJobKey}
149
+			child_jobid = #{childJobId}
150 150
 		WHERE id = #{id}
151 151
 	</update>
152 152
 	

+ 5 - 6
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl Просмотреть файл

@@ -66,9 +66,8 @@
66 66
 			              	<table id="job_list" class="table table-bordered table-striped" width="100%" >
67 67
 				                <thead>
68 68
 					            	<tr>
69
-					            		<th name="id" >id</th>
69
+					            		<th name="id" >任务ID</th>
70 70
 					                	<th name="jobGroup" >jobGroup</th>
71
-                                        <th name="childJobKey" >JobKey</th>
72 71
 					                  	<th name="jobDesc" >描述</th>
73 72
                                         <th name="glueType" >运行模式</th>
74 73
 					                  	<th name="executorParam" >任务参数</th>
@@ -144,8 +143,8 @@
144 143
                     <div class="form-group">
145 144
                         <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
146 145
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="512" ></div>
147
-                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
148
-                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
146
+                        <label for="lastname" class="col-sm-2 control-label">子任务ID<font color="black">*</font></label>
147
+                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="请输入子任务的任务ID,如存在多个逗号分隔" maxlength="100" ></div>
149 148
                     </div>
150 149
                     <div class="form-group">
151 150
                         <label for="firstname" class="col-sm-2 control-label">阻塞处理策略<font color="red">*</font></label>
@@ -312,8 +311,8 @@ process.exit(0)
312 311
                     <div class="form-group">
313 312
                         <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
314 313
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="512" ></div>
315
-                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
316
-                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
314
+                        <label for="lastname" class="col-sm-2 control-label">子任务ID<font color="black">*</font></label>
315
+                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="请输入子任务的任务ID,如存在多个逗号分隔" maxlength="100" ></div>
317 316
                     </div>
318 317
                     <div class="form-group">
319 318
                         <label for="firstname" class="col-sm-2 control-label">阻塞处理策略<font color="red">*</font></label>

+ 1 - 3
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl Просмотреть файл

@@ -90,10 +90,8 @@
90 90
 			              	<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
91 91
 				                <thead>
92 92
 					            	<tr>
93
-					                	<th name="id" >id</th>
93
+                                        <th name="jobId" >任务ID</th>
94 94
                                         <th name="jobGroup" >执行器ID</th>
95
-					                	<th name="jobId" >任务ID</th>
96
-                                        <th name="JobKey" >JobKey</th>
97 95
 										<#--<th name="executorAddress" >执行器地址</th>
98 96
 										<th name="glueType" >运行模式</th>
99 97
                                       	<th name="executorParam" >任务参数</th>-->

+ 2 - 11
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js Просмотреть файл

@@ -20,7 +20,7 @@ $(function() {
20 20
 	    "ordering": false,
21 21
 	    //"scrollX": true,	// X轴滚动条,取消自适应
22 22
 	    "columns": [
23
-	                { "data": 'id', "bSortable": false, "visible" : false},
23
+	                { "data": 'id', "bSortable": false, "visible" : true},
24 24
 	                { 
25 25
 	                	"data": 'jobGroup', 
26 26
 	                	"visible" : false,
@@ -34,15 +34,6 @@ $(function() {
34 34
 	            			return data;
35 35
 	            		}
36 36
             		},
37
-					{
38
-						"data": 'childJobKey',
39
-						"width":'10%',
40
-						"visible" : true,
41
-						"render": function ( data, type, row ) {
42
-							var jobKey = row.jobGroup + "_" + row.id;
43
-							return jobKey;
44
-						}
45
-					},
46 37
 	                { "data": 'jobDesc', "visible" : true,"width":'20%'},
47 38
 					{
48 39
 						"data": 'glueType',
@@ -372,7 +363,7 @@ $(function() {
372 363
 		$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
373 364
 		$("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
374 365
 		$("#updateModal .form input[name='executorParam']").val( row.executorParam );
375
-        $("#updateModal .form input[name='childJobKey']").val( row.childJobKey );
366
+        $("#updateModal .form input[name='childJobId']").val( row.childJobId );
376 367
 		$('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
377 368
 		$('#updateModal .form select[name=executorFailStrategy] option[value='+ row.executorFailStrategy +']').prop('selected', true);
378 369
 		$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);

+ 19 - 41
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js Просмотреть файл

@@ -89,54 +89,32 @@ $(function() {
89 89
 	    "ordering": false,
90 90
 	    //"scrollX": false,
91 91
 	    "columns": [
92
-	                { "data": 'id', "bSortable": false, "visible" : false},
93
-					{ "data": 'jobGroup', "visible" : false},
94
-	                { "data": 'jobId', "visible" : false},
95 92
 					{
96
-						"data": 'JobKey',
93
+						"data": 'jobId',
97 94
 						"visible" : true,
98 95
 						"render": function ( data, type, row ) {
99
-							var jobKey = row.jobGroup + "_" + row.jobId;
100
-
101
-                            var glueTypeTitle = row.glueType;
102
-                            if ('GLUE_GROOVY'==row.glueType) {
103
-                                glueTypeTitle = "GLUE模式(Java)";
104
-                            } else if ('GLUE_SHELL'==row.glueType) {
105
-                                glueTypeTitle = "GLUE模式(Shell)";
106
-                            } else if ('GLUE_PYTHON'==row.glueType) {
107
-                                glueTypeTitle = "GLUE模式(Python)";
108
-                            }else if ('GLUE_NODEJS'==row.glueType) {
109
-                            	glueTypeTitle = "GLUE模式(Nodejs)";
110
-                            } else if ('BEAN'==row.glueType) {
111
-                                glueTypeTitle = "BEAN模式:" + row.executorHandler;
112
-                            }
96
+							var glueTypeTitle = row.glueType;
97
+							if ('GLUE_GROOVY'==row.glueType) {
98
+								glueTypeTitle = "GLUE模式(Java)";
99
+							} else if ('GLUE_SHELL'==row.glueType) {
100
+								glueTypeTitle = "GLUE模式(Shell)";
101
+							} else if ('GLUE_PYTHON'==row.glueType) {
102
+								glueTypeTitle = "GLUE模式(Python)";
103
+							}else if ('GLUE_NODEJS'==row.glueType) {
104
+								glueTypeTitle = "GLUE模式(Nodejs)";
105
+							} else if ('BEAN'==row.glueType) {
106
+								glueTypeTitle = "BEAN模式:" + row.executorHandler;
107
+							}
113 108
 
114
-                            var temp = '';
115
-                            temp += '执行器地址:' + (row.executorAddress?row.executorAddress:'');
116
-                            temp += '<br>运行模式:' + glueTypeTitle;
117
-                            temp += '<br>任务参数:' + row.executorParam;
109
+							var temp = '';
110
+							temp += '执行器地址:' + (row.executorAddress?row.executorAddress:'');
111
+							temp += '<br>运行模式:' + glueTypeTitle;
112
+							temp += '<br>任务参数:' + row.executorParam;
118 113
 
119
-                            return '<a class="logTips" href="javascript:;" >'+ jobKey +'<span style="display:none;">'+ temp +'</span></a>';
114
+							return '<a class="logTips" href="javascript:;" >'+ row.jobId +'<span style="display:none;">'+ temp +'</span></a>';
120 115
 						}
121 116
 					},
122
-					// { "data": 'executorAddress', "visible" : true},
123
-					// {
124
-					// 	"data": 'glueType',
125
-					//  	"visible" : true,
126
-					// 	"render": function ( data, type, row ) {
127
-					// 		if ('GLUE_GROOVY'==row.glueType) {
128
-					// 			return "GLUE模式(Java)";
129
-					// 		} else if ('GLUE_SHELL'==row.glueType) {
130
-					// 		 	return "GLUE模式(Shell)";
131
-					// 		} else if ('GLUE_PYTHON'==row.glueType) {
132
-					// 			return "GLUE模式(Python)";
133
-					// 		} else if ('BEAN'==row.glueType) {
134
-					// 		 	return "BEAN模式:" + row.executorHandler;
135
-					// 		}
136
-					// 		return row.executorHandler;
137
-					// 	 }
138
-					// },
139
-					// { "data": 'executorParam', "visible" : true},
117
+					{ "data": 'jobGroup', "visible" : false},
140 118
 					{
141 119
 						"data": 'triggerTime',
142 120
 						"render": function ( data, type, row ) {

+ 2 - 2
xxl-job-admin/src/test/java/com/xxl/job/admin/dao/XxlJobInfoDaoTest.java Просмотреть файл

@@ -45,7 +45,7 @@ public class XxlJobInfoDaoTest {
45 45
 		info.setGlueType("setGlueType");
46 46
 		info.setGlueSource("setGlueSource");
47 47
 		info.setGlueRemark("setGlueRemark");
48
-		info.setChildJobKey("setChildJobKey");
48
+		info.setChildJobId("1");
49 49
 
50 50
 		int count = xxlJobInfoDao.save(info);
51 51
 
@@ -63,7 +63,7 @@ public class XxlJobInfoDaoTest {
63 63
 		info2.setGlueSource("setGlueSource2");
64 64
 		info2.setGlueRemark("setGlueRemark2");
65 65
 		info2.setGlueUpdatetime(new Date());
66
-		info2.setChildJobKey("setChildJobKey2");
66
+		info2.setChildJobId("1");
67 67
 
68 68
 		int item2 = xxlJobInfoDao.update(info2);
69 69
 

+ 4 - 3
xxl-job-admin/src/test/java/com/xxl/job/admin/util/MailUtilTest.java Просмотреть файл

@@ -20,7 +20,7 @@ public class MailUtilTest {
20 20
                 "   <thead style=\"font-weight: bold;color: #ffffff;background-color: #ff8c00;\" >" +
21 21
                 "      <tr>\n" +
22 22
                 "         <td>执行器</td>\n" +
23
-                "         <td>JobKey</td>\n" +
23
+                "         <td>任务ID</td>\n" +
24 24
                 "         <td>任务描述</td>\n" +
25 25
                 "         <td>告警类型</td>\n" +
26 26
                 "      </tr>\n" +
@@ -35,9 +35,10 @@ public class MailUtilTest {
35 35
                 "   <tbody>\n" +
36 36
                 "</table>";
37 37
 
38
-        mailBodyTemplate = MessageFormat.format(mailBodyTemplate, "执行器A", "1_1", "任务A1");
38
+        String title = "调度中心监控报警";
39
+        String content = MessageFormat.format(mailBodyTemplate, "执行器A", "01", "任务A1");
39 40
 
40
-        boolean ret = MailUtil.sendMail("931591021@qq.com", "调度中心监控报警" , mailBodyTemplate);
41
+        boolean ret = MailUtil.sendMail("931591021@qq.com", title, content);
41 42
         System.out.println(ret);
42 43
     }
43 44