瀏覽代碼

- 1、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度;

xueli.xue 8 年之前
父節點
當前提交
370c816355

+ 2 - 2
README.md 查看文件

825
 - 8、升级quartz版本至2.3.0;
825
 - 8、升级quartz版本至2.3.0;
826
 
826
 
827
 #### 6.15 版本 V1.7.2 特性(Coding)
827
 #### 6.15 版本 V1.7.2 特性(Coding)
828
-- 1、阻塞处理机制:单机串行(默认)、并行、丢弃、覆盖
829
-- 2、失败处理机制;失败告警(默认)、失败重试;
828
+- 1、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度
829
+- 2、失败处理策略;调度失败时的处理策略,策略包括:失败告警(默认)、失败重试;
830
 
830
 
831
 #### TODO LIST
831
 #### TODO LIST
832
 - 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
832
 - 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;

+ 2 - 0
db/tables_xxl_job.sql 查看文件

157
   `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
157
   `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
158
   `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
158
   `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
159
   `executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数',
159
   `executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数',
160
+  `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
161
+  `executor_fail_strategy` varchar(50) DEFAULT NULL COMMENT '失败处理策略',
160
   `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
162
   `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
161
   `glue_source` text COMMENT 'GLUE源代码',
163
   `glue_source` text COMMENT 'GLUE源代码',
162
   `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
164
   `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',

+ 7 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java 查看文件

1
 package com.xxl.job.admin.controller;
1
 package com.xxl.job.admin.controller;
2
 
2
 
3
+import com.xxl.job.admin.core.enums.ExecutorFailStrategyEnum;
3
 import com.xxl.job.admin.core.model.XxlJobGroup;
4
 import com.xxl.job.admin.core.model.XxlJobGroup;
4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5
 import com.xxl.job.admin.core.model.XxlJobInfo;
5
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
6
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
6
 import com.xxl.job.admin.dao.IXxlJobGroupDao;
7
 import com.xxl.job.admin.dao.IXxlJobGroupDao;
7
 import com.xxl.job.admin.service.IXxlJobService;
8
 import com.xxl.job.admin.service.IXxlJobService;
8
 import com.xxl.job.core.biz.model.ReturnT;
9
 import com.xxl.job.core.biz.model.ReturnT;
10
+import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
9
 import com.xxl.job.core.glue.GlueTypeEnum;
11
 import com.xxl.job.core.glue.GlueTypeEnum;
10
 import org.springframework.stereotype.Controller;
12
 import org.springframework.stereotype.Controller;
11
 import org.springframework.ui.Model;
13
 import org.springframework.ui.Model;
33
 	@RequestMapping
35
 	@RequestMapping
34
 	public String index(Model model) {
36
 	public String index(Model model) {
35
 
37
 
36
-		// 路由策略-列表
37
-		model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());
38
-
39
-		// Glue类型-字典
40
-		model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());
38
+		// 枚举-字典
39
+		model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());	// 路由策略-列表
40
+		model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());								// Glue类型-字典
41
+		model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values());	// 阻塞处理策略-字典
42
+		model.addAttribute("ExecutorFailStrategyEnum", ExecutorFailStrategyEnum.values());		// 失败处理策略-字典
41
 
43
 
42
 		// 任务组
44
 		// 任务组
43
 		List<XxlJobGroup> jobGroupList =  xxlJobGroupDao.findAll();
45
 		List<XxlJobGroup> jobGroupList =  xxlJobGroupDao.findAll();

+ 32 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/enums/ExecutorFailStrategyEnum.java 查看文件

1
+package com.xxl.job.admin.core.enums;
2
+
3
+/**
4
+ * Created by xuxueli on 17/5/9.
5
+ */
6
+public enum ExecutorFailStrategyEnum {
7
+
8
+    FAIL_ALARM("失败告警"),
9
+
10
+    FAIL_RETRY("失败重试");
11
+
12
+    private final String title;
13
+    private ExecutorFailStrategyEnum(String title) {
14
+        this.title = title;
15
+    }
16
+
17
+    public String getTitle() {
18
+        return title;
19
+    }
20
+
21
+    public static ExecutorFailStrategyEnum match(String name, ExecutorFailStrategyEnum defaultItem) {
22
+        if (name != null) {
23
+            for (ExecutorFailStrategyEnum item: ExecutorFailStrategyEnum.values()) {
24
+                if (item.name().equals(name)) {
25
+                    return item;
26
+                }
27
+            }
28
+        }
29
+        return defaultItem;
30
+    }
31
+
32
+}

+ 18 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java 查看文件

23
 	private String executorRouteStrategy;	// 执行器路由策略
23
 	private String executorRouteStrategy;	// 执行器路由策略
24
 	private String executorHandler;		    // 执行器,任务Handler名称
24
 	private String executorHandler;		    // 执行器,任务Handler名称
25
 	private String executorParam;		    // 执行器,任务参数
25
 	private String executorParam;		    // 执行器,任务参数
26
+	private String executorBlockStrategy;	// 阻塞处理策略
27
+	private String executorFailStrategy;	// 失败处理策略
26
 	
28
 	
27
 	private String glueType;		// GLUE类型	#com.xxl.job.core.glue.GlueTypeEnum
29
 	private String glueType;		// GLUE类型	#com.xxl.job.core.glue.GlueTypeEnum
28
 	private String glueSource;		// GLUE源代码
30
 	private String glueSource;		// GLUE源代码
122
 		this.executorParam = executorParam;
124
 		this.executorParam = executorParam;
123
 	}
125
 	}
124
 
126
 
127
+	public String getExecutorBlockStrategy() {
128
+		return executorBlockStrategy;
129
+	}
130
+
131
+	public void setExecutorBlockStrategy(String executorBlockStrategy) {
132
+		this.executorBlockStrategy = executorBlockStrategy;
133
+	}
134
+
135
+	public String getExecutorFailStrategy() {
136
+		return executorFailStrategy;
137
+	}
138
+
139
+	public void setExecutorFailStrategy(String executorFailStrategy) {
140
+		this.executorFailStrategy = executorFailStrategy;
141
+	}
142
+
125
 	public String getGlueType() {
143
 	public String getGlueType() {
126
 		return glueType;
144
 		return glueType;
127
 	}
145
 	}

+ 34 - 18
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java 查看文件

1
 package com.xxl.job.admin.service.impl;
1
 package com.xxl.job.admin.service.impl;
2
 
2
 
3
+import com.xxl.job.admin.core.enums.ExecutorFailStrategyEnum;
3
 import com.xxl.job.admin.core.model.XxlJobGroup;
4
 import com.xxl.job.admin.core.model.XxlJobGroup;
4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5
 import com.xxl.job.admin.core.model.XxlJobInfo;
5
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
6
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
8
 import com.xxl.job.admin.dao.*;
9
 import com.xxl.job.admin.dao.*;
9
 import com.xxl.job.admin.service.IXxlJobService;
10
 import com.xxl.job.admin.service.IXxlJobService;
10
 import com.xxl.job.core.biz.model.ReturnT;
11
 import com.xxl.job.core.biz.model.ReturnT;
12
+import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
11
 import com.xxl.job.core.glue.GlueTypeEnum;
13
 import com.xxl.job.core.glue.GlueTypeEnum;
12
 import com.xxl.job.core.registry.RegistHelper;
14
 import com.xxl.job.core.registry.RegistHelper;
13
 import org.apache.commons.collections.CollectionUtils;
15
 import org.apache.commons.collections.CollectionUtils;
68
 		// valid
70
 		// valid
69
 		XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
71
 		XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
70
 		if (group == null) {
72
 		if (group == null) {
71
-			return new ReturnT<String>(500, "请选择“执行器”");
73
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请选择“执行器”");
72
 		}
74
 		}
73
 		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
75
 		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
74
-			return new ReturnT<String>(500, "请输入格式正确的“Cron”");
76
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入格式正确的“Cron”");
75
 		}
77
 		}
76
 		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
78
 		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
77
-			return new ReturnT<String>(500, "请输入“任务描述”");
79
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入“任务描述”");
78
 		}
80
 		}
79
 		if (StringUtils.isBlank(jobInfo.getAuthor())) {
81
 		if (StringUtils.isBlank(jobInfo.getAuthor())) {
80
-			return new ReturnT<String>(500, "请输入“负责人”");
82
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入“负责人”");
81
 		}
83
 		}
82
 		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
84
 		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
83
-			return new ReturnT<String>(500, "路由策略非法");
85
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "路由策略非法");
86
+		}
87
+		if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
88
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "阻塞处理策略非法");
89
+		}
90
+		if (ExecutorFailStrategyEnum.match(jobInfo.getExecutorFailStrategy(), null) == null) {
91
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "失败处理策略非法");
84
 		}
92
 		}
85
 		if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
93
 		if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
86
-			return new ReturnT<String>(500, "运行模式非法非法");
94
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "运行模式非法非法");
87
 		}
95
 		}
88
 		if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) {
96
 		if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) {
89
-			return new ReturnT<String>(500, "请输入“JobHandler”");
97
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入“JobHandler”");
90
 		}
98
 		}
91
 
99
 
92
 		// fix "\r" in shell
100
 		// fix "\r" in shell
100
 			for (String childJobKeyItem: childJobKeys) {
108
 			for (String childJobKeyItem: childJobKeys) {
101
 				String[] childJobKeyArr = childJobKeyItem.split("_");
109
 				String[] childJobKeyArr = childJobKeyItem.split("_");
102
 				if (childJobKeyArr.length!=2) {
110
 				if (childJobKeyArr.length!=2) {
103
-					return new ReturnT<String>(500, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
111
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
104
 				}
112
 				}
105
 				XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobKeyArr[1]));
113
 				XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobKeyArr[1]));
106
 				if (childJobInfo==null) {
114
 				if (childJobInfo==null) {
107
-					return new ReturnT<String>(500, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
115
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
108
 				}
116
 				}
109
 			}
117
 			}
110
 		}
118
 		}
112
 		// add in db
120
 		// add in db
113
 		xxlJobInfoDao.save(jobInfo);
121
 		xxlJobInfoDao.save(jobInfo);
114
 		if (jobInfo.getId() < 1) {
122
 		if (jobInfo.getId() < 1) {
115
-			return new ReturnT<String>(500, "新增任务失败");
123
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "新增任务失败");
116
 		}
124
 		}
117
 
125
 
118
 		// add in quartz
126
 		// add in quartz
130
             } catch (SchedulerException e1) {
138
             } catch (SchedulerException e1) {
131
                 logger.error("", e1);
139
                 logger.error("", e1);
132
             }
140
             }
133
-            return new ReturnT<String>(500, "新增任务失败:" + e.getMessage());
141
+            return new ReturnT<String>(ReturnT.FAIL_CODE, "新增任务失败:" + e.getMessage());
134
         }
142
         }
135
 	}
143
 	}
136
 
144
 
139
 
147
 
140
 		// valid
148
 		// valid
141
 		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
149
 		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
142
-			return new ReturnT<String>(500, "请输入格式正确的“Cron”");
150
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入格式正确的“Cron”");
143
 		}
151
 		}
144
 		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
152
 		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
145
-			return new ReturnT<String>(500, "请输入“任务描述”");
153
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入“任务描述”");
146
 		}
154
 		}
147
 		if (StringUtils.isBlank(jobInfo.getAuthor())) {
155
 		if (StringUtils.isBlank(jobInfo.getAuthor())) {
148
-			return new ReturnT<String>(500, "请输入“负责人”");
156
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "请输入“负责人”");
149
 		}
157
 		}
150
 		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
158
 		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
151
-			return new ReturnT<String>(500, "路由策略非法");
159
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "路由策略非法");
160
+		}
161
+		if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
162
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "阻塞处理策略非法");
163
+		}
164
+		if (ExecutorFailStrategyEnum.match(jobInfo.getExecutorFailStrategy(), null) == null) {
165
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "失败处理策略非法");
152
 		}
166
 		}
153
 
167
 
154
 		// childJobKey valid
168
 		// childJobKey valid
157
 			for (String childJobKeyItem: childJobKeys) {
171
 			for (String childJobKeyItem: childJobKeys) {
158
 				String[] childJobKeyArr = childJobKeyItem.split("_");
172
 				String[] childJobKeyArr = childJobKeyItem.split("_");
159
 				if (childJobKeyArr.length!=2) {
173
 				if (childJobKeyArr.length!=2) {
160
-					return new ReturnT<String>(500, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
174
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})格式错误", childJobKeyItem));
161
 				}
175
 				}
162
                 XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobKeyArr[1]));
176
                 XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobKeyArr[1]));
163
 				if (childJobInfo==null) {
177
 				if (childJobInfo==null) {
164
-					return new ReturnT<String>(500, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
178
+					return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format("子任务Key({0})无效", childJobKeyItem));
165
 				}
179
 				}
166
 			}
180
 			}
167
 		}
181
 		}
170
 		XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
184
 		XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
171
         String old_cron = exists_jobInfo.getJobCron();
185
         String old_cron = exists_jobInfo.getJobCron();
172
 		if (exists_jobInfo == null) {
186
 		if (exists_jobInfo == null) {
173
-			return new ReturnT<String>(500, "参数异常");
187
+			return new ReturnT<String>(ReturnT.FAIL_CODE, "参数异常");
174
 		}
188
 		}
175
 
189
 
176
 		exists_jobInfo.setJobCron(jobInfo.getJobCron());
190
 		exists_jobInfo.setJobCron(jobInfo.getJobCron());
180
 		exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
194
 		exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
181
 		exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
195
 		exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
182
 		exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
196
 		exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
197
+		exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
198
+		exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy());
183
 		exists_jobInfo.setChildJobKey(jobInfo.getChildJobKey());
199
 		exists_jobInfo.setChildJobKey(jobInfo.getChildJobKey());
184
         xxlJobInfoDao.update(exists_jobInfo);
200
         xxlJobInfoDao.update(exists_jobInfo);
185
 
201
 

+ 11 - 1
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml 查看文件

19
 		<result column="executor_route_strategy" property="executorRouteStrategy" />
19
 		<result column="executor_route_strategy" property="executorRouteStrategy" />
20
 		<result column="executor_handler" property="executorHandler" />
20
 		<result column="executor_handler" property="executorHandler" />
21
 	    <result column="executor_param" property="executorParam" />
21
 	    <result column="executor_param" property="executorParam" />
22
+		<result column="executor_block_strategy" property="executorBlockStrategy" />
23
+		<result column="executor_fail_strategy" property="executorFailStrategy" />
22
 	    
24
 	    
23
 	    <result column="glue_type" property="glueType" />
25
 	    <result column="glue_type" property="glueType" />
24
 	    <result column="glue_source" property="glueSource" />
26
 	    <result column="glue_source" property="glueSource" />
40
 		t.executor_route_strategy,
42
 		t.executor_route_strategy,
41
 		t.executor_handler,
43
 		t.executor_handler,
42
 		t.executor_param,
44
 		t.executor_param,
45
+		t.executor_block_strategy,
46
+		t.executor_fail_strategy,
43
 		t.glue_type,
47
 		t.glue_type,
44
 		t.glue_source,
48
 		t.glue_source,
45
 		t.glue_remark,
49
 		t.glue_remark,
87
             executor_route_strategy,
91
             executor_route_strategy,
88
 			executor_handler,
92
 			executor_handler,
89
 			executor_param,
93
 			executor_param,
90
-		glue_type,
94
+			executor_block_strategy,
95
+			executor_fail_strategy,
96
+			glue_type,
91
 			glue_source,
97
 			glue_source,
92
 			glue_remark,
98
 			glue_remark,
93
 			glue_updatetime,
99
 			glue_updatetime,
103
 			#{executorRouteStrategy},
109
 			#{executorRouteStrategy},
104
 			#{executorHandler},
110
 			#{executorHandler},
105
 			#{executorParam},
111
 			#{executorParam},
112
+			#{executorBlockStrategy},
113
+			#{executorFailStrategy},
106
 			#{glueType},
114
 			#{glueType},
107
 			#{glueSource},
115
 			#{glueSource},
108
 			#{glueRemark},
116
 			#{glueRemark},
132
 			executor_route_strategy = #{executorRouteStrategy},
140
 			executor_route_strategy = #{executorRouteStrategy},
133
 			executor_handler = #{executorHandler},
141
 			executor_handler = #{executorHandler},
134
 			executor_param = #{executorParam},
142
 			executor_param = #{executorParam},
143
+			executor_block_strategy = #{executorBlockStrategy},
144
+			executor_fail_strategy = #{executorFailStrategy},
135
 			glue_type = #{glueType},
145
 			glue_type = #{glueType},
136
 			glue_source = #{glueSource},
146
 			glue_source = #{glueSource},
137
 			glue_remark = #{glueRemark},
147
 			glue_remark = #{glueRemark},

+ 36 - 0
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl 查看文件

153
                         <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
153
                         <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
154
                         <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
154
                         <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
155
                     </div>
155
                     </div>
156
+                    <div class="form-group">
157
+                        <label for="firstname" class="col-sm-2 control-label">阻塞处理策略<font color="red">*</font></label>
158
+                        <div class="col-sm-4">
159
+                            <select class="form-control" name="executorBlockStrategy" >
160
+								<#list ExecutorBlockStrategyEnum as item>
161
+									<option value="${item}" >${item.title}</option>
162
+								</#list>
163
+                            </select>
164
+						</div>
165
+                        <label for="lastname" class="col-sm-2 control-label">失败处理策略<font color="red">*</font></label>
166
+                        <div class="col-sm-4">
167
+                            <select class="form-control" name="executorFailStrategy" >
168
+								<#list ExecutorFailStrategyEnum as item>
169
+									<option value="${item}" >${item.title}</option>
170
+								</#list>
171
+                            </select>
172
+						</div>
173
+                    </div>
156
 					<div class="form-group">
174
 					<div class="form-group">
157
                         <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
175
                         <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
158
                         <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
176
                         <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
280
                         <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
298
                         <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
281
                     </div>
299
                     </div>
282
                     <div class="form-group">
300
                     <div class="form-group">
301
+                        <label for="firstname" class="col-sm-2 control-label">阻塞处理策略<font color="red">*</font></label>
302
+                        <div class="col-sm-4">
303
+                            <select class="form-control" name="executorBlockStrategy" >
304
+							<#list ExecutorBlockStrategyEnum as item>
305
+                                <option value="${item}" >${item.title}</option>
306
+							</#list>
307
+                            </select>
308
+                        </div>
309
+                        <label for="lastname" class="col-sm-2 control-label">失败处理策略<font color="red">*</font></label>
310
+                        <div class="col-sm-4">
311
+                            <select class="form-control" name="executorFailStrategy" >
312
+							<#list ExecutorFailStrategyEnum as item>
313
+                                <option value="${item}" >${item.title}</option>
314
+							</#list>
315
+                            </select>
316
+                        </div>
317
+                    </div>
318
+                    <div class="form-group">
283
                         <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
319
                         <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
284
                         <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
320
                         <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
285
                         <label for="lastname" class="col-sm-2 control-label">报警邮件<font color="black">*</font></label>
321
                         <label for="lastname" class="col-sm-2 control-label">报警邮件<font color="black">*</font></label>

+ 30 - 25
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js 查看文件

118
 								}
118
 								}
119
 
119
 
120
 								// html
120
 								// html
121
-								var html = '<p id="'+ row.id +'" '+
122
-									' jobGroup="'+ row.jobGroup +'" '+
123
-									' jobCron="'+ row.jobCron +'" '+
124
-									' jobDesc="'+ row.jobDesc +'" '+
125
-									' author="'+ row.author +'" '+
126
-									' alarmEmail="'+ row.alarmEmail +'" '+
127
-									' executorRouteStrategy="'+row.executorRouteStrategy +'" '+
128
-									' executorHandler="'+row.executorHandler +'" '+
129
-									' executorParam="'+ row.executorParam +'" '+
130
-									' glueType="'+ row.glueType +'" '+
131
-                                    ' childJobKey="'+ row.childJobKey +'" '+
132
-									'>'+
121
+                                tableData['key'+row.id] = row;
122
+								var html = '<p id="'+ row.id +'" >'+
133
 									'<button class="btn btn-primary btn-xs job_operate" _type="job_trigger" type="button">执行</button>  '+
123
 									'<button class="btn btn-primary btn-xs job_operate" _type="job_trigger" type="button">执行</button>  '+
134
 									pause_resume +
124
 									pause_resume +
135
 									'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br>  '+
125
 									'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br>  '+
168
 			}
158
 			}
169
 		}
159
 		}
170
 	});
160
 	});
171
-	
161
+
162
+    // table data
163
+    var tableData = {};
164
+
172
 	// 搜索按钮
165
 	// 搜索按钮
173
 	$('#searchBtn').on('click', function(){
166
 	$('#searchBtn').on('click', function(){
174
 		jobTable.fnDraw();
167
 		jobTable.fnDraw();
347
 	// 更新
340
 	// 更新
348
 	$("#job_list").on('click', '.update',function() {
341
 	$("#job_list").on('click', '.update',function() {
349
 
342
 
350
-		// base data
351
-		$("#updateModal .form input[name='id']").val($(this).parent('p').attr("id"));
352
-		$('#updateModal .form select[name=jobGroup] option[value='+ $(this).parent('p').attr("jobGroup") +']').prop('selected', true);
353
-		$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
354
-		$("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron"));
355
-		$("#updateModal .form input[name='author']").val($(this).parent('p').attr("author"));
356
-		$("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail"));
357
-		$('#updateModal .form select[name=executorRouteStrategy] option[value='+ $(this).parent('p').attr("executorRouteStrategy") +']').prop('selected', true);
358
-		$("#updateModal .form input[name='executorHandler']").val($(this).parent('p').attr("executorHandler"));
359
-		$("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam"));
360
-        $("#updateModal .form input[name='childJobKey']").val($(this).parent('p').attr("childJobKey"));
361
-		$('#updateModal .form select[name=glueType] option[value='+ $(this).parent('p').attr("glueType") +']').prop('selected', true);
343
+        var id = $(this).parent('p').attr("id");
344
+        var row = tableData['key'+id];
345
+        if (!row) {
346
+            layer.open({
347
+                title: '系统提示',
348
+                content: ("任务信息加载失败,请刷新页面"),
349
+                icon: '2'
350
+            });
351
+            return;
352
+        }
362
 
353
 
354
+		// base data
355
+		$("#updateModal .form input[name='id']").val( row.id );
356
+		$('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
357
+		$("#updateModal .form input[name='jobDesc']").val( row.jobDesc );
358
+		$("#updateModal .form input[name='jobCron']").val( row.jobCron );
359
+		$("#updateModal .form input[name='author']").val( row.author );
360
+		$("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
361
+		$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
362
+		$("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
363
+		$("#updateModal .form input[name='executorParam']").val( row.executorParam );
364
+        $("#updateModal .form input[name='childJobKey']").val( row.childJobKey );
365
+		$('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
366
+		$('#updateModal .form select[name=executorFailStrategy] option[value='+ row.executorFailStrategy +']').prop('selected', true);
367
+		$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
363
 
368
 
364
         $("#updateModal .form select[name=glueType]").change();
369
         $("#updateModal .form select[name=glueType]").change();
365
 
370
 

+ 31 - 0
xxl-job-core/src/main/java/com/xxl/job/core/enums/ExecutorBlockStrategyEnum.java 查看文件

1
+package com.xxl.job.core.enums;
2
+
3
+/**
4
+ * Created by xuxueli on 17/5/9.
5
+ */
6
+public enum ExecutorBlockStrategyEnum {
7
+
8
+    SERIAL_EXECUTION("单机串行"),
9
+    /*CONCURRENT_EXECUTION("并行"),*/
10
+    DISCARD_LATER("丢弃后续调度"),
11
+    COVER_EARLY("覆盖之前调度");
12
+
13
+    private final String title;
14
+    private ExecutorBlockStrategyEnum (String title) {
15
+        this.title = title;
16
+    }
17
+    public String getTitle() {
18
+        return title;
19
+    }
20
+
21
+    public static ExecutorBlockStrategyEnum match(String name, ExecutorBlockStrategyEnum defaultItem) {
22
+        if (name != null) {
23
+            for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
24
+                if (item.name().equals(name)) {
25
+                    return item;
26
+                }
27
+            }
28
+        }
29
+        return defaultItem;
30
+    }
31
+}