Ver Fonte

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

xuxueli há 7 anos atrás
pai
commit
4ce20c1038

+ 7 - 5
doc/XXL-JOB官方文档.md

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

+ 1 - 1
doc/db/tables_xxl_job.sql

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

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java

@@ -31,7 +31,7 @@ public class XxlJobInfo {
 	private String glueRemark;		// GLUE备注
 	private Date glueUpdatetime;	// GLUE更新时间
 
-	private String childJobKey;		// 子任务Key
+	private String childJobId;		// 子任务ID,多个逗号分隔
 	
 	// copy from quartz
 	private String jobStatus;		// 任务状态 【base on quartz】
@@ -172,12 +172,12 @@ public class XxlJobInfo {
 		this.glueUpdatetime = glueUpdatetime;
 	}
 
-	public String getChildJobKey() {
-		return childJobKey;
+	public String getChildJobId() {
+		return childJobId;
 	}
 
-	public void setChildJobKey(String childJobKey) {
-		this.childJobKey = childJobKey;
+	public void setChildJobId(String childJobId) {
+		this.childJobId = childJobId;
 	}
 
 	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;
 import com.xxl.job.admin.core.model.XxlJobInfo;
 import com.xxl.job.admin.core.model.XxlJobLog;
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
-import com.xxl.job.admin.core.util.JobKeyUtil;
 import com.xxl.job.admin.core.util.MailUtil;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.IJobHandler;
@@ -125,7 +124,7 @@ public class JobFailMonitorHelper {
 			"   <thead style=\"font-weight: bold;color: #ffffff;background-color: #ff8c00;\" >" +
 			"      <tr>\n" +
 			"         <td>执行器</td>\n" +
-			"         <td>JobKey</td>\n" +
+			"         <td>任务ID</td>\n" +
 			"         <td>任务描述</td>\n" +
 			"         <td>告警类型</td>\n" +
 			"      </tr>\n" +
@@ -156,7 +155,7 @@ public class JobFailMonitorHelper {
 				XxlJobGroup group = XxlJobDynamicScheduler.xxlJobGroupDao.load(Integer.valueOf(info.getJobGroup()));
 
 				String title = "调度中心监控报警";
-				String content = MessageFormat.format(mailBodyTemplate, group!=null?group.getTitle():"null", JobKeyUtil.formatJobKey(info), info.getJobDesc());
+				String content = MessageFormat.format(mailBodyTemplate, group!=null?group.getTitle():"null", info.getId(), info.getJobDesc());
 
 				MailUtil.sendMail(email, title, content);
 			}

+ 0 - 44
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JobKeyUtil.java

@@ -1,44 +0,0 @@
-package com.xxl.job.admin.core.util;
-
-import com.xxl.job.admin.core.model.XxlJobInfo;
-import org.apache.commons.lang3.StringUtils;
-
-/**
- * job key util
- *
- * @author xuxueli 2017-12-22 18:48:45
- */
-public class JobKeyUtil {
-
-    /**
-     * format job key
-     *
-     * @param xxlJobInfo
-     * @return
-     */
-    public static String formatJobKey(XxlJobInfo xxlJobInfo){
-        return String.valueOf(xxlJobInfo.getJobGroup())
-                .concat("_").concat(String.valueOf(xxlJobInfo.getId()));
-    }
-
-    /**
-     * parse jobId from JobKey
-     *
-     * @param jobKey
-     * @return
-     */
-    public static int parseJobId(String jobKey){
-        if (jobKey!=null && jobKey.trim().length()>0) {
-            String[] jobKeyArr = jobKey.split("_");
-            if (jobKeyArr.length == 2) {
-                String jobIdStr = jobKeyArr[1];
-                if (StringUtils.isNotBlank(jobIdStr) && StringUtils.isNumeric(jobIdStr)) {
-                    int jobId = Integer.valueOf(jobIdStr);
-                    return jobId;
-                }
-            }
-        }
-        return -1;
-    }
-
-}

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

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

+ 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;
 import com.xxl.job.admin.core.model.XxlJobInfo;
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
-import com.xxl.job.admin.core.util.JobKeyUtil;
 import com.xxl.job.admin.dao.XxlJobGroupDao;
 import com.xxl.job.admin.dao.XxlJobInfoDao;
 import com.xxl.job.admin.dao.XxlJobLogDao;
@@ -104,19 +103,20 @@ public class XxlJobServiceImpl implements XxlJobService {
 			jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
 		}
 
-		// childJobKey valid
-		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
-			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
-			for (String childJobKeyItem: childJobKeys) {
-				int childJobId = JobKeyUtil.parseJobId(childJobKeyItem);
-				if (childJobId <= 0) {
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
-				}
-				XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(childJobId);
-				if (childJobInfo==null) {
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
+		// ChildJobId valid
+		if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
+			String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
+			for (String childJobIdItem: childJobIds) {
+				if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
+					XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
+					if (childJobInfo==null) {
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})无效", childJobIdItem));
+					}
+				} else {
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})格式错误", childJobIdItem));
 				}
 			}
+			jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
 		}
 
 		// add in db
@@ -167,19 +167,24 @@ public class XxlJobServiceImpl implements XxlJobService {
 			return new ReturnT<String>(ReturnT.FAIL_CODE, "失败处理策略非法");
 		}
 
-		// childJobKey valid
-		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
-			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
-			for (String childJobKeyItem: childJobKeys) {
-				int childJobId = JobKeyUtil.parseJobId(childJobKeyItem);
-				if (childJobId <= 0) {
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
-				}
-                XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(childJobId);
-				if (childJobInfo==null) {
-					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
+		// ChildJobId valid
+		if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
+			String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
+			for (String childJobIdItem: childJobIds) {
+				if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
+					XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
+					if (childJobInfo==null) {
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})无效", childJobIdItem));
+					}
+					// avoid cycle relate
+					if (childJobInfo.getId() == jobInfo.getId()) {
+						return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})不可与父任务重复", childJobIdItem));
+					}
+				} else {
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务ID({0})格式错误", childJobIdItem));
 				}
 			}
+			jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
 		}
 
 		// stage job info
@@ -198,7 +203,7 @@ public class XxlJobServiceImpl implements XxlJobService {
 		exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
 		exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
 		exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy());
-		exists_jobInfo.setChildJobKey(jobInfo.getChildJobKey());
+		exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
         xxlJobInfoDao.update(exists_jobInfo);
 
 		// fresh quartz

+ 5 - 5
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml

@@ -27,7 +27,7 @@
 	    <result column="glue_remark" property="glueRemark" />
 		<result column="glue_updatetime" property="glueUpdatetime" />
 
-		<result column="child_jobkey" property="childJobKey" />
+		<result column="child_jobid" property="childJobId" />
 	</resultMap>
 
 	<sql id="Base_Column_List">
@@ -48,7 +48,7 @@
 		t.glue_source,
 		t.glue_remark,
 		t.glue_updatetime,
-		t.child_jobkey
+		t.child_jobid
 	</sql>
 	
 	<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
@@ -97,7 +97,7 @@
 			glue_source,
 			glue_remark,
 			glue_updatetime,
-			child_jobkey
+			child_jobid
 		) VALUES (
 			#{jobGroup},
 			#{jobCron}, 
@@ -115,7 +115,7 @@
 			#{glueSource},
 			#{glueRemark},
 			NOW(),
-			#{childJobKey}
+			#{childJobId}
 		);
 		<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
 			SELECT LAST_INSERT_ID()
@@ -146,7 +146,7 @@
 			glue_source = #{glueSource},
 			glue_remark = #{glueRemark},
 			glue_updatetime = #{glueUpdatetime},
-			child_jobkey = #{childJobKey}
+			child_jobid = #{childJobId}
 		WHERE id = #{id}
 	</update>
 	

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

@@ -66,9 +66,8 @@
 			              	<table id="job_list" class="table table-bordered table-striped" width="100%" >
 				                <thead>
 					            	<tr>
-					            		<th name="id" >id</th>
+					            		<th name="id" >任务ID</th>
 					                	<th name="jobGroup" >jobGroup</th>
-                                        <th name="childJobKey" >JobKey</th>
 					                  	<th name="jobDesc" >描述</th>
                                         <th name="glueType" >运行模式</th>
 					                  	<th name="executorParam" >任务参数</th>
@@ -144,8 +143,8 @@
                     <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="512" ></div>
-                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
+                        <label for="lastname" class="col-sm-2 control-label">子任务ID<font color="black">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="请输入子任务的任务ID,如存在多个逗号分隔" maxlength="100" ></div>
                     </div>
                     <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">阻塞处理策略<font color="red">*</font></label>
@@ -312,8 +311,8 @@ process.exit(0)
                     <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="512" ></div>
-                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
+                        <label for="lastname" class="col-sm-2 control-label">子任务ID<font color="black">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="请输入子任务的任务ID,如存在多个逗号分隔" maxlength="100" ></div>
                     </div>
                     <div class="form-group">
                         <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 @@
 			              	<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
 				                <thead>
 					            	<tr>
-					                	<th name="id" >id</th>
+                                        <th name="jobId" >任务ID</th>
                                         <th name="jobGroup" >执行器ID</th>
-					                	<th name="jobId" >任务ID</th>
-                                        <th name="JobKey" >JobKey</th>
 										<#--<th name="executorAddress" >执行器地址</th>
 										<th name="glueType" >运行模式</th>
                                       	<th name="executorParam" >任务参数</th>-->

+ 2 - 11
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js

@@ -20,7 +20,7 @@ $(function() {
 	    "ordering": false,
 	    //"scrollX": true,	// X轴滚动条,取消自适应
 	    "columns": [
-	                { "data": 'id', "bSortable": false, "visible" : false},
+	                { "data": 'id', "bSortable": false, "visible" : true},
 	                { 
 	                	"data": 'jobGroup', 
 	                	"visible" : false,
@@ -34,15 +34,6 @@ $(function() {
 	            			return data;
 	            		}
             		},
-					{
-						"data": 'childJobKey',
-						"width":'10%',
-						"visible" : true,
-						"render": function ( data, type, row ) {
-							var jobKey = row.jobGroup + "_" + row.id;
-							return jobKey;
-						}
-					},
 	                { "data": 'jobDesc', "visible" : true,"width":'20%'},
 					{
 						"data": 'glueType',
@@ -372,7 +363,7 @@ $(function() {
 		$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
 		$("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
 		$("#updateModal .form input[name='executorParam']").val( row.executorParam );
-        $("#updateModal .form input[name='childJobKey']").val( row.childJobKey );
+        $("#updateModal .form input[name='childJobId']").val( row.childJobId );
 		$('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
 		$('#updateModal .form select[name=executorFailStrategy] option[value='+ row.executorFailStrategy +']').prop('selected', true);
 		$('#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() {
 	    "ordering": false,
 	    //"scrollX": false,
 	    "columns": [
-	                { "data": 'id', "bSortable": false, "visible" : false},
-					{ "data": 'jobGroup', "visible" : false},
-	                { "data": 'jobId', "visible" : false},
 					{
-						"data": 'JobKey',
+						"data": 'jobId',
 						"visible" : true,
 						"render": function ( data, type, row ) {
-							var jobKey = row.jobGroup + "_" + row.jobId;
-
-                            var glueTypeTitle = row.glueType;
-                            if ('GLUE_GROOVY'==row.glueType) {
-                                glueTypeTitle = "GLUE模式(Java)";
-                            } else if ('GLUE_SHELL'==row.glueType) {
-                                glueTypeTitle = "GLUE模式(Shell)";
-                            } else if ('GLUE_PYTHON'==row.glueType) {
-                                glueTypeTitle = "GLUE模式(Python)";
-                            }else if ('GLUE_NODEJS'==row.glueType) {
-                            	glueTypeTitle = "GLUE模式(Nodejs)";
-                            } else if ('BEAN'==row.glueType) {
-                                glueTypeTitle = "BEAN模式:" + row.executorHandler;
-                            }
+							var glueTypeTitle = row.glueType;
+							if ('GLUE_GROOVY'==row.glueType) {
+								glueTypeTitle = "GLUE模式(Java)";
+							} else if ('GLUE_SHELL'==row.glueType) {
+								glueTypeTitle = "GLUE模式(Shell)";
+							} else if ('GLUE_PYTHON'==row.glueType) {
+								glueTypeTitle = "GLUE模式(Python)";
+							}else if ('GLUE_NODEJS'==row.glueType) {
+								glueTypeTitle = "GLUE模式(Nodejs)";
+							} else if ('BEAN'==row.glueType) {
+								glueTypeTitle = "BEAN模式:" + row.executorHandler;
+							}
 
-                            var temp = '';
-                            temp += '执行器地址:' + (row.executorAddress?row.executorAddress:'');
-                            temp += '<br>运行模式:' + glueTypeTitle;
-                            temp += '<br>任务参数:' + row.executorParam;
+							var temp = '';
+							temp += '执行器地址:' + (row.executorAddress?row.executorAddress:'');
+							temp += '<br>运行模式:' + glueTypeTitle;
+							temp += '<br>任务参数:' + row.executorParam;
 
-                            return '<a class="logTips" href="javascript:;" >'+ jobKey +'<span style="display:none;">'+ temp +'</span></a>';
+							return '<a class="logTips" href="javascript:;" >'+ row.jobId +'<span style="display:none;">'+ temp +'</span></a>';
 						}
 					},
-					// { "data": 'executorAddress', "visible" : true},
-					// {
-					// 	"data": 'glueType',
-					//  	"visible" : true,
-					// 	"render": function ( data, type, row ) {
-					// 		if ('GLUE_GROOVY'==row.glueType) {
-					// 			return "GLUE模式(Java)";
-					// 		} else if ('GLUE_SHELL'==row.glueType) {
-					// 		 	return "GLUE模式(Shell)";
-					// 		} else if ('GLUE_PYTHON'==row.glueType) {
-					// 			return "GLUE模式(Python)";
-					// 		} else if ('BEAN'==row.glueType) {
-					// 		 	return "BEAN模式:" + row.executorHandler;
-					// 		}
-					// 		return row.executorHandler;
-					// 	 }
-					// },
-					// { "data": 'executorParam', "visible" : true},
+					{ "data": 'jobGroup', "visible" : false},
 					{
 						"data": 'triggerTime',
 						"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 {
 		info.setGlueType("setGlueType");
 		info.setGlueSource("setGlueSource");
 		info.setGlueRemark("setGlueRemark");
-		info.setChildJobKey("setChildJobKey");
+		info.setChildJobId("1");
 
 		int count = xxlJobInfoDao.save(info);
 
@@ -63,7 +63,7 @@ public class XxlJobInfoDaoTest {
 		info2.setGlueSource("setGlueSource2");
 		info2.setGlueRemark("setGlueRemark2");
 		info2.setGlueUpdatetime(new Date());
-		info2.setChildJobKey("setChildJobKey2");
+		info2.setChildJobId("1");
 
 		int item2 = xxlJobInfoDao.update(info2);
 

+ 4 - 3
xxl-job-admin/src/test/java/com/xxl/job/admin/util/MailUtilTest.java

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