xueli.xue 8 years ago
parent
commit
628d421941

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

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

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

@@ -15,6 +15,7 @@ public class XxlJobLog {
 	private String jobName;
 	
 	private String executorAddress;	// 执行器地址,有多个则逗号分隔
+	private String executorHandler;	// 执行器Handler
 	private String executorParam;	// 执行器,任务参数
 	
 	// trigger info
@@ -51,6 +52,12 @@ public class XxlJobLog {
 	public void setExecutorAddress(String executorAddress) {
 		this.executorAddress = executorAddress;
 	}
+	public String getExecutorHandler() {
+		return executorHandler;
+	}
+	public void setExecutorHandler(String executorHandler) {
+		this.executorHandler = executorHandler;
+	}
 	public String getExecutorParam() {
 		return executorParam;
 	}

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

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

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

@@ -10,6 +10,7 @@
 	    <result column="job_name" property="jobName" />
 	    
 	    <result column="executor_address" property="executorAddress" />
+		<result column="executor_handler" property="executorHandler" />
 	    <result column="executor_param" property="executorParam" />
 	    
 	    <result column="trigger_time" property="triggerTime" />
@@ -27,6 +28,7 @@
 		t.job_group,
 		t.job_name,
 		t.executor_address,
+		t.executor_handler,
 		t.executor_param,
 		t.trigger_time,
 		t.trigger_status,
@@ -94,11 +96,13 @@
 			`job_group`,
 			`job_name`,
 			`executor_address`,
+			`executor_handler`,
 			`executor_param`
 		) VALUES (
 			#{jobGroup}, 
 			#{jobName},
 			#{executorAddress},
+			#{executorHandler},
 			#{executorParam}
 		);
 		<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> 
@@ -113,6 +117,7 @@
 			`trigger_status`= #{triggerStatus}, 
 			`trigger_msg`= #{triggerMsg},
 			`executor_address`= #{executorAddress},
+			`executor_handler`=#{executorHandler},
 			`executor_param`= #{executorParam}
 		WHERE `id`= #{id}
 	</update>

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

@@ -40,7 +40,7 @@
 	    	<div class="row">
 	    		<div class="col-xs-4">
 	              	<div class="input-group">
-	                	<span class="input-group-addon">组</span>
+	                	<span class="input-group-addon">任务组</span>
                 		<select class="form-control" id="jobGroup" >
                 			<#list JobGroupList as group>
                 				<option value="${group}" >${group.desc}</option>
@@ -113,7 +113,7 @@
          	<div class="modal-body">
 				<form class="form-horizontal form" role="form" >
 					<div class="form-group">
-						<label for="firstname" class="col-sm-2 control-label">组<font color="red">*</font></label>
+						<label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
 						<div class="col-sm-4">
 							<select class="form-control" name="jobGroup" >
 		            			<#list JobGroupList as group>
@@ -194,7 +194,7 @@ public class DemoJobHandler extends IJobHandler {
          	<div class="modal-body">
 				<form class="form-horizontal form" role="form" >
 					<div class="form-group">
-                        <label for="firstname" class="col-sm-2 control-label">组<font color="red">*</font></label>
+                        <label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
                         <div class="col-sm-4">
 							<input type="text" class="form-control jobGroupTitle" maxlength="50" readonly >
 						</div>

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

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

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

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

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

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

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

@@ -38,6 +38,10 @@ public class HandlerRepository {
 		 * job name
 		 */
 		JOB_NAME,
+		/**
+		 * params of jobhandler
+		 */
+		EXECUTOR_HANDLER,
 		/**
 		 * params of jobhandler
 		 */
@@ -60,21 +64,27 @@ public class HandlerRepository {
 		LOG_DATE
 	}
 	public enum ActionEnum{RUN, KILL, LOG, BEAT}
-	
+
+	// jobhandler repository
+	private static ConcurrentHashMap<String, IJobHandler> handlerRepository = new ConcurrentHashMap<String, IJobHandler>();
+	public static void registJobHandler(String name, IJobHandler jobHandler){
+		handlerRepository.put(name, jobHandler);
+		logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
+	}
+
+	// thread repository of jobhandler
 	public static ConcurrentHashMap<String, HandlerThread> handlerTreadMap = new ConcurrentHashMap<String, HandlerThread>();
-	
-	// regist handler
-	public static void regist(String handleName, IJobHandler handler){
+	public static HandlerThread registJobHandlerThread(String jobkey, IJobHandler handler){
 		HandlerThread handlerThread = new HandlerThread(handler);
 		handlerThread.start();
-		handlerTreadMap.put(handleName, handlerThread);	// putIfAbsent
-		logger.info(">>>>>>>>>>> xxl-job regist handler success, handleName:{}, handler:{}", new Object[]{handleName, handler});
+		logger.info(">>>>>>>>>>> xxl-job regist handler success, jobkey:{}, handler:{}", new Object[]{jobkey, handler});
+		return handlerTreadMap.put(jobkey, handlerThread);	// putIfAbsent
 	}
-	
+
 	// handler push to queue
 	public static String service(Map<String, String> _param) {
 		logger.debug(">>>>>>>>>>> xxl-job service start, _param:{}", new Object[]{_param});
-		
+
 		// callback
 		RemoteCallBack callback = new RemoteCallBack();
 		callback.setStatus(RemoteCallBack.FAIL);
@@ -91,7 +101,7 @@ public class HandlerRepository {
 			callback.setMsg("Timestamp check failed.");
 			return JacksonUtil.writeValueAsString(callback);
 		}
-					
+
 		// parse namespace
 		if (namespace.equals(ActionEnum.RUN.name())) {
 
@@ -110,20 +120,40 @@ public class HandlerRepository {
 				return JacksonUtil.writeValueAsString(callback);
 			}
 
+			// load old thread
 			String jobKey = job_group.concat("_").concat(job_name);
 			HandlerThread handlerThread = handlerTreadMap.get(jobKey);
+
 			if ("0".equals(handler_glue_switch)) {
 				// bean model
-				if (handlerThread == null) {
-					callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
+
+				// handler name
+				String executor_handler = _param.get(HandlerParamEnum.EXECUTOR_HANDLER.name());
+				if (executor_handler==null || executor_handler.trim().length()==0){
+					callback.setMsg("EXECUTOR_HANDLER is null.");
 					return JacksonUtil.writeValueAsString(callback);
 				}
+
+				// handler instance
+				IJobHandler jobHandler = handlerRepository.get(executor_handler);
+
+				if (handlerThread == null) {
+					// jobhandler match
+					if (jobHandler==null) {
+						callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
+						return JacksonUtil.writeValueAsString(callback);
+					}
+					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
+				} else {
+					if (handlerThread.getHandler() != jobHandler) {
+						handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
+					}
+				}
 			} else {
 				// glue
-				if (handlerThread==null) {
-					HandlerRepository.regist(jobKey, new GlueJobHandler(job_group, job_name));
+				if (handlerThread == null) {
+					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, new GlueJobHandler(job_group, job_name));
 				}
-				handlerThread = handlerTreadMap.get(jobKey);
 			}
 
 			// push data to queue
@@ -145,7 +175,7 @@ public class HandlerRepository {
 				IJobHandler handler = handlerThread.getHandler();
 				handlerThread.toStop();
 				handlerThread.interrupt();
-				regist(jobKey, handler);
+				HandlerRepository.registJobHandlerThread(jobKey, handler);
 				callback.setStatus(RemoteCallBack.SUCCESS);
 			} else {
 				callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
@@ -179,11 +209,11 @@ public class HandlerRepository {
 			callback.setMsg("param[Action] is not valid.");
 			return JacksonUtil.writeValueAsString(callback);
 		}
-		
+
 		logger.debug(">>>>>>>>>>> xxl-job service end, triggerData:{}");
-		return JacksonUtil.writeValueAsString(callback); 
+		return JacksonUtil.writeValueAsString(callback);
 	}
-	
+
 	// ----------------------- for callback log -----------------------
 	private static LinkedBlockingQueue<HashMap<String, String>> callBackQueue = new LinkedBlockingQueue<HashMap<String, String>>();
 	static {

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

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