xueli.xue il y a 9 ans
Parent
révision
628d421941

+ 2 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java Voir le fichier

@@ -52,12 +52,14 @@ public class RemoteHttpJobBean extends QuartzJobBean {
52 52
 
53 53
 		params.put(HandlerParamEnum.JOB_GROUP.name(), jobInfo.getJobGroup());
54 54
 		params.put(HandlerParamEnum.JOB_NAME.name(), jobInfo.getJobName());
55
+		params.put(HandlerParamEnum.EXECUTOR_HANDLER.name(), jobInfo.getExecutorHandler());
55 56
 		params.put(HandlerParamEnum.EXECUTOR_PARAMS.name(), jobInfo.getExecutorParam());
56 57
 
57 58
 		params.put(HandlerParamEnum.GLUE_SWITCH.name(), String.valueOf(jobInfo.getGlueSwitch()));
58 59
 
59 60
 		// failover trigger
60 61
 		RemoteCallBack callback = failoverTrigger(jobInfo.getExecutorAddress(), params, jobLog);
62
+		jobLog.setExecutorHandler(jobInfo.getExecutorHandler());
61 63
 		jobLog.setExecutorParam(jobInfo.getExecutorParam());
62 64
 		logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, callback:{}", jobLog.getId(), callback);
63 65
 		

+ 7 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java Voir le fichier

@@ -15,6 +15,7 @@ public class XxlJobLog {
15 15
 	private String jobName;
16 16
 	
17 17
 	private String executorAddress;	// 执行器地址,有多个则逗号分隔
18
+	private String executorHandler;	// 执行器Handler
18 19
 	private String executorParam;	// 执行器,任务参数
19 20
 	
20 21
 	// trigger info
@@ -51,6 +52,12 @@ public class XxlJobLog {
51 52
 	public void setExecutorAddress(String executorAddress) {
52 53
 		this.executorAddress = executorAddress;
53 54
 	}
55
+	public String getExecutorHandler() {
56
+		return executorHandler;
57
+	}
58
+	public void setExecutorHandler(String executorHandler) {
59
+		this.executorHandler = executorHandler;
60
+	}
54 61
 	public String getExecutorParam() {
55 62
 		return executorParam;
56 63
 	}

+ 10 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobMonitorHelper.java Voir le fichier

@@ -10,6 +10,9 @@ import org.slf4j.Logger;
10 10
 import org.slf4j.LoggerFactory;
11 11
 
12 12
 import java.text.MessageFormat;
13
+import java.util.Arrays;
14
+import java.util.HashSet;
15
+import java.util.Set;
13 16
 import java.util.concurrent.*;
14 17
 
15 18
 /**
@@ -51,8 +54,13 @@ public class JobMonitorHelper {
51 54
 								if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) {
52 55
 									XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName());
53 56
 									if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
54
-										MailUtil.sendMail(info.getAlarmEmail(), "《调度监控报警-调度平台平台XXL-JOB》",
55
-												MessageFormat.format("任务调度失败, 任务组:{0}, 任务描述:{1}.", info.getJobGroup(), info.getJobDesc()), false, null);
57
+
58
+										Set<String> emailSet = new HashSet<String>(Arrays.asList(info.getAlarmEmail().split(",")));
59
+										for (String email: emailSet) {
60
+											String title = "《调度监控报警-调度平台平台XXL-JOB》";
61
+											String content = MessageFormat.format("任务调度失败, 任务组:{0}, 任务描述:{1}.", info.getJobGroup(), info.getJobDesc());
62
+											MailUtil.sendMail(email, title, content, false, null);
63
+										}
56 64
 									}
57 65
 								}
58 66
 							}

+ 5 - 0
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml Voir le fichier

@@ -10,6 +10,7 @@
10 10
 	    <result column="job_name" property="jobName" />
11 11
 	    
12 12
 	    <result column="executor_address" property="executorAddress" />
13
+		<result column="executor_handler" property="executorHandler" />
13 14
 	    <result column="executor_param" property="executorParam" />
14 15
 	    
15 16
 	    <result column="trigger_time" property="triggerTime" />
@@ -27,6 +28,7 @@
27 28
 		t.job_group,
28 29
 		t.job_name,
29 30
 		t.executor_address,
31
+		t.executor_handler,
30 32
 		t.executor_param,
31 33
 		t.trigger_time,
32 34
 		t.trigger_status,
@@ -94,11 +96,13 @@
94 96
 			`job_group`,
95 97
 			`job_name`,
96 98
 			`executor_address`,
99
+			`executor_handler`,
97 100
 			`executor_param`
98 101
 		) VALUES (
99 102
 			#{jobGroup}, 
100 103
 			#{jobName},
101 104
 			#{executorAddress},
105
+			#{executorHandler},
102 106
 			#{executorParam}
103 107
 		);
104 108
 		<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> 
@@ -113,6 +117,7 @@
113 117
 			`trigger_status`= #{triggerStatus}, 
114 118
 			`trigger_msg`= #{triggerMsg},
115 119
 			`executor_address`= #{executorAddress},
120
+			`executor_handler`=#{executorHandler},
116 121
 			`executor_param`= #{executorParam}
117 122
 		WHERE `id`= #{id}
118 123
 	</update>

+ 3 - 3
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl Voir le fichier

@@ -40,7 +40,7 @@
40 40
 	    	<div class="row">
41 41
 	    		<div class="col-xs-4">
42 42
 	              	<div class="input-group">
43
-	                	<span class="input-group-addon">组</span>
43
+	                	<span class="input-group-addon">任务组</span>
44 44
                 		<select class="form-control" id="jobGroup" >
45 45
                 			<#list JobGroupList as group>
46 46
                 				<option value="${group}" >${group.desc}</option>
@@ -113,7 +113,7 @@
113 113
          	<div class="modal-body">
114 114
 				<form class="form-horizontal form" role="form" >
115 115
 					<div class="form-group">
116
-						<label for="firstname" class="col-sm-2 control-label">组<font color="red">*</font></label>
116
+						<label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
117 117
 						<div class="col-sm-4">
118 118
 							<select class="form-control" name="jobGroup" >
119 119
 		            			<#list JobGroupList as group>
@@ -194,7 +194,7 @@ public class DemoJobHandler extends IJobHandler {
194 194
          	<div class="modal-body">
195 195
 				<form class="form-horizontal form" role="form" >
196 196
 					<div class="form-group">
197
-                        <label for="firstname" class="col-sm-2 control-label">组<font color="red">*</font></label>
197
+                        <label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
198 198
                         <div class="col-sm-4">
199 199
 							<input type="text" class="form-control jobGroupTitle" maxlength="50" readonly >
200 200
 						</div>

+ 3 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl Voir le fichier

@@ -34,7 +34,7 @@
34 34
 	    	<div class="row">
35 35
 	    		<div class="col-xs-3">
36 36
  					<div class="input-group">
37
-	                	<span class="input-group-addon">组</span>
37
+	                	<span class="input-group-addon">任务组</span>
38 38
                 		<select class="form-control" id="jobGroup"  paramVal="${jobGroup}" >
39 39
                             <option value="" selected>请选择</option>
40 40
                 			<#list JobGroupList as group>
@@ -45,7 +45,7 @@
45 45
 	            </div>
46 46
 	            <div class="col-xs-3">
47 47
 	              	<div class="input-group">
48
-	                	<span class="input-group-addon">名称</span>
48
+	                	<span class="input-group-addon">描述</span>
49 49
                         <select class="form-control" id="jobName" paramVal="${jobName}" >
50 50
                             <option value="" >请选择</option>
51 51
 						</select>
@@ -79,6 +79,7 @@
79 79
 					                	<th name="jobGroup" >任务组</th>
80 80
 					                  	<th name="jobName" >任务名</th>
81 81
 					                  	<th name="executorAddress" >执行器地址</th>
82
+                                        <th name="executorHandler" >JobHandler</th>
82 83
 					                  	<th name="executorParam" >任务参数</th>
83 84
 					                  	<th name="triggerTime" >调度时间</th>
84 85
 					                  	<th name="triggerStatus" >调度结果</th>

+ 2 - 1
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js Voir le fichier

@@ -1,6 +1,6 @@
1 1
 $(function() {
2 2
 
3
-	// 组列表选中, 任务列表初始化和选中
3
+	// 任务组列表选中, 任务列表初始化和选中
4 4
     var ifParam = true;
5 5
 	$("#jobGroup").on("change", function () {
6 6
 		var jobGroup = $(this).children('option:selected').val();
@@ -97,6 +97,7 @@ $(function() {
97 97
             		},
98 98
 	                { "data": 'jobName', "visible" : false},
99 99
 	                { "data": 'executorAddress', "visible" : true},
100
+					{ "data": 'executorHandler', "visible" : true},
100 101
 	                { "data": 'executorParam', "visible" : true},
101 102
 	                { 
102 103
 	                	"data": 'triggerTime', 

+ 7 - 13
xxl-job-core/src/main/java/com/xxl/job/core/executor/jetty/XxlJobExecutor.java Voir le fichier

@@ -1,7 +1,8 @@
1 1
 package com.xxl.job.core.executor.jetty;
2 2
 
3
-import java.util.*;
4
-
3
+import com.xxl.job.core.handler.HandlerRepository;
4
+import com.xxl.job.core.handler.IJobHandler;
5
+import com.xxl.job.core.handler.annotation.JobHander;
5 6
 import org.eclipse.jetty.server.Connector;
6 7
 import org.eclipse.jetty.server.Handler;
7 8
 import org.eclipse.jetty.server.Server;
@@ -14,9 +15,7 @@ import org.springframework.beans.BeansException;
14 15
 import org.springframework.context.ApplicationContext;
15 16
 import org.springframework.context.ApplicationContextAware;
16 17
 
17
-import com.xxl.job.core.handler.HandlerRepository;
18
-import com.xxl.job.core.handler.IJobHandler;
19
-import com.xxl.job.core.handler.annotation.JobHander;
18
+import java.util.Map;
20 19
 
21 20
 /**
22 21
  * Created by xuxueli on 2016/3/2 21:14.
@@ -89,14 +88,9 @@ public class XxlJobExecutor implements ApplicationContextAware {
89 88
         if (serviceBeanMap!=null && serviceBeanMap.size()>0) {
90 89
             for (Object serviceBean : serviceBeanMap.values()) {
91 90
                 if (serviceBean instanceof IJobHandler){
92
-                    String jobKeys = serviceBean.getClass().getAnnotation(JobHander.class).value();
93
-                    if (jobKeys!=null && jobKeys.trim().length()>0) {
94
-                        Set<String> jobKeySet = new HashSet<String>(Arrays.asList(jobKeys.split(",")));
95
-                        for (String jobKey : jobKeySet) {
96
-                            IJobHandler handler = (IJobHandler) serviceBean;
97
-                            HandlerRepository.regist(jobKey, handler);
98
-                        }
99
-                    }
91
+                    String name = serviceBean.getClass().getAnnotation(JobHander.class).value();
92
+                    IJobHandler handler = (IJobHandler) serviceBean;
93
+                    HandlerRepository.registJobHandler(name, handler);
100 94
                 }
101 95
             }
102 96
         }

+ 48 - 18
xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerRepository.java Voir le fichier

@@ -41,6 +41,10 @@ public class HandlerRepository {
41 41
 		/**
42 42
 		 * params of jobhandler
43 43
 		 */
44
+		EXECUTOR_HANDLER,
45
+		/**
46
+		 * params of jobhandler
47
+		 */
44 48
 		EXECUTOR_PARAMS,
45 49
 		/**
46 50
 		 * switch of glue job: 0-no,1-yes
@@ -60,21 +64,27 @@ public class HandlerRepository {
60 64
 		LOG_DATE
61 65
 	}
62 66
 	public enum ActionEnum{RUN, KILL, LOG, BEAT}
63
-	
67
+
68
+	// jobhandler repository
69
+	private static ConcurrentHashMap<String, IJobHandler> handlerRepository = new ConcurrentHashMap<String, IJobHandler>();
70
+	public static void registJobHandler(String name, IJobHandler jobHandler){
71
+		handlerRepository.put(name, jobHandler);
72
+		logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
73
+	}
74
+
75
+	// thread repository of jobhandler
64 76
 	public static ConcurrentHashMap<String, HandlerThread> handlerTreadMap = new ConcurrentHashMap<String, HandlerThread>();
65
-	
66
-	// regist handler
67
-	public static void regist(String handleName, IJobHandler handler){
77
+	public static HandlerThread registJobHandlerThread(String jobkey, IJobHandler handler){
68 78
 		HandlerThread handlerThread = new HandlerThread(handler);
69 79
 		handlerThread.start();
70
-		handlerTreadMap.put(handleName, handlerThread);	// putIfAbsent
71
-		logger.info(">>>>>>>>>>> xxl-job regist handler success, handleName:{}, handler:{}", new Object[]{handleName, handler});
80
+		logger.info(">>>>>>>>>>> xxl-job regist handler success, jobkey:{}, handler:{}", new Object[]{jobkey, handler});
81
+		return handlerTreadMap.put(jobkey, handlerThread);	// putIfAbsent
72 82
 	}
73
-	
83
+
74 84
 	// handler push to queue
75 85
 	public static String service(Map<String, String> _param) {
76 86
 		logger.debug(">>>>>>>>>>> xxl-job service start, _param:{}", new Object[]{_param});
77
-		
87
+
78 88
 		// callback
79 89
 		RemoteCallBack callback = new RemoteCallBack();
80 90
 		callback.setStatus(RemoteCallBack.FAIL);
@@ -91,7 +101,7 @@ public class HandlerRepository {
91 101
 			callback.setMsg("Timestamp check failed.");
92 102
 			return JacksonUtil.writeValueAsString(callback);
93 103
 		}
94
-					
104
+
95 105
 		// parse namespace
96 106
 		if (namespace.equals(ActionEnum.RUN.name())) {
97 107
 
@@ -110,20 +120,40 @@ public class HandlerRepository {
110 120
 				return JacksonUtil.writeValueAsString(callback);
111 121
 			}
112 122
 
123
+			// load old thread
113 124
 			String jobKey = job_group.concat("_").concat(job_name);
114 125
 			HandlerThread handlerThread = handlerTreadMap.get(jobKey);
126
+
115 127
 			if ("0".equals(handler_glue_switch)) {
116 128
 				// bean model
117
-				if (handlerThread == null) {
118
-					callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
129
+
130
+				// handler name
131
+				String executor_handler = _param.get(HandlerParamEnum.EXECUTOR_HANDLER.name());
132
+				if (executor_handler==null || executor_handler.trim().length()==0){
133
+					callback.setMsg("EXECUTOR_HANDLER is null.");
119 134
 					return JacksonUtil.writeValueAsString(callback);
120 135
 				}
136
+
137
+				// handler instance
138
+				IJobHandler jobHandler = handlerRepository.get(executor_handler);
139
+
140
+				if (handlerThread == null) {
141
+					// jobhandler match
142
+					if (jobHandler==null) {
143
+						callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
144
+						return JacksonUtil.writeValueAsString(callback);
145
+					}
146
+					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
147
+				} else {
148
+					if (handlerThread.getHandler() != jobHandler) {
149
+						handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
150
+					}
151
+				}
121 152
 			} else {
122 153
 				// glue
123
-				if (handlerThread==null) {
124
-					HandlerRepository.regist(jobKey, new GlueJobHandler(job_group, job_name));
154
+				if (handlerThread == null) {
155
+					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, new GlueJobHandler(job_group, job_name));
125 156
 				}
126
-				handlerThread = handlerTreadMap.get(jobKey);
127 157
 			}
128 158
 
129 159
 			// push data to queue
@@ -145,7 +175,7 @@ public class HandlerRepository {
145 175
 				IJobHandler handler = handlerThread.getHandler();
146 176
 				handlerThread.toStop();
147 177
 				handlerThread.interrupt();
148
-				regist(jobKey, handler);
178
+				HandlerRepository.registJobHandlerThread(jobKey, handler);
149 179
 				callback.setStatus(RemoteCallBack.SUCCESS);
150 180
 			} else {
151 181
 				callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
@@ -179,11 +209,11 @@ public class HandlerRepository {
179 209
 			callback.setMsg("param[Action] is not valid.");
180 210
 			return JacksonUtil.writeValueAsString(callback);
181 211
 		}
182
-		
212
+
183 213
 		logger.debug(">>>>>>>>>>> xxl-job service end, triggerData:{}");
184
-		return JacksonUtil.writeValueAsString(callback); 
214
+		return JacksonUtil.writeValueAsString(callback);
185 215
 	}
186
-	
216
+
187 217
 	// ----------------------- for callback log -----------------------
188 218
 	private static LinkedBlockingQueue<HashMap<String, String>> callBackQueue = new LinkedBlockingQueue<HashMap<String, String>>();
189 219
 	static {

+ 1 - 1
xxl-job-executor-example/src/main/java/com/xxl/job/executor/service/jobhandler/DemoJobHandler.java Voir le fichier

@@ -20,7 +20,7 @@ import com.xxl.job.core.handler.annotation.JobHander;
20 20
  * 
21 21
  * @author xuxueli 2015-12-19 19:43:36
22 22
  */
23
-@JobHander(value="waimai_201607202316260736,waimai_201607202316260736")
23
+@JobHander(value="demoJobHandler")
24 24
 @Service
25 25
 public class DemoJobHandler extends IJobHandler {
26 26
 	private static transient Logger logger = LoggerFactory.getLogger(DemoJobHandler.class);