Browse Source

GLUE模式任务实例更新逻辑优化,原根据超时时间更新改为根据版本号更新,源码变动版本号加一;

xueli.xue 8 years ago
parent
commit
3ccf3ad5ab

+ 1 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java View File

@@ -60,6 +60,7 @@ public class RemoteHttpJobBean extends QuartzJobBean {
60 60
 		triggerParam.setExecutorHandler(jobInfo.getExecutorHandler());
61 61
 		triggerParam.setExecutorParams(jobInfo.getExecutorParam());
62 62
 		triggerParam.setGlueSwitch((jobInfo.getGlueSwitch()==0)?false:true);
63
+		triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
63 64
 		triggerParam.setLogId(jobLog.getId());
64 65
 		triggerParam.setLogDateTim(jobLog.getTriggerTime().getTime());
65 66
 		triggerParam.setLogAddress(findCallbackAddressList());		// callback address list

+ 35 - 21
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java View File

@@ -9,6 +9,8 @@ import com.xxl.job.core.handler.IJobHandler;
9 9
 import com.xxl.job.core.handler.impl.GlueJobHandler;
10 10
 import com.xxl.job.core.log.XxlJobFileAppender;
11 11
 import com.xxl.job.core.thread.JobThread;
12
+import org.slf4j.Logger;
13
+import org.slf4j.LoggerFactory;
12 14
 
13 15
 import java.util.Date;
14 16
 
@@ -16,6 +18,7 @@ import java.util.Date;
16 18
  * Created by xuxueli on 17/3/1.
17 19
  */
18 20
 public class ExecutorBizImpl implements ExecutorBiz {
21
+    private static Logger logger = LoggerFactory.getLogger(ExecutorBizImpl.class);
19 22
 
20 23
     @Override
21 24
     public ReturnT<String> beat() {
@@ -55,25 +58,26 @@ public class ExecutorBizImpl implements ExecutorBiz {
55 58
         if (!triggerParam.isGlueSwitch()) {
56 59
             // bean model
57 60
 
58
-            // valid handler instance
61
+            // valid handler
59 62
             IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());
60 63
             if (jobHandler==null) {
61 64
                 return new ReturnT(ReturnT.FAIL_CODE, "job handler for JobId=[" + triggerParam.getJobId() + "] not found.");
62 65
             }
63 66
 
67
+            // valid exists job thread:change handler, need kill old thread
68
+            if (jobThread != null && jobThread.getHandler() != jobHandler) {
69
+                // kill old job thread
70
+                jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
71
+                jobThread.interrupt();
72
+                XxlJobExecutor.removeJobThread(triggerParam.getJobId());
73
+                jobThread = null;
74
+            }
75
+
76
+            // make thread: new or exists invalid
64 77
             if (jobThread == null) {
65 78
                 jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), jobHandler);
66
-            } else {
67
-                // job handler update, kill old job thread
68
-                if (jobThread.getHandler() != jobHandler) {
69
-                    // kill old job thread
70
-                    jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
71
-                    jobThread.interrupt();
72
-
73
-                    // new thread, with new job handler
74
-                    jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), jobHandler);
75
-                }
76 79
             }
80
+
77 81
         } else {
78 82
             // glue model
79 83
 
@@ -82,19 +86,29 @@ public class ExecutorBizImpl implements ExecutorBiz {
82 86
                 return new ReturnT(ReturnT.FAIL_CODE, "glueLoader for JobId=[" + triggerParam.getJobId() + "] not found.");
83 87
             }
84 88
 
89
+            // valid exists job thread:change handler or glue timeout, need kill old thread
90
+            if (jobThread != null &&
91
+                    !(jobThread.getHandler() instanceof GlueJobHandler
92
+                        && ((GlueJobHandler) jobThread.getHandler()).getGlueUpdatetime()==triggerParam.getGlueUpdatetime() )) {
93
+                // change glue model or glue timeout, kill old job thread
94
+                jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
95
+                jobThread.interrupt();
96
+                XxlJobExecutor.removeJobThread(triggerParam.getJobId());
97
+                jobThread = null;
98
+            }
99
+
100
+            // make thread: new or exists invalid
85 101
             if (jobThread == null) {
86
-                jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), new GlueJobHandler(triggerParam.getJobId()));
87
-            } else {
88
-                // job handler update, kill old job thread
89
-                if (!(jobThread.getHandler() instanceof GlueJobHandler)) {
90
-                    // kill old job thread
91
-                    jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
92
-                    jobThread.interrupt();
93
-
94
-                    // new thread, with new job handler
95
-                    jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), new GlueJobHandler(triggerParam.getJobId()));
102
+                IJobHandler jobHandler = null;
103
+                try {
104
+                    jobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getJobId());
105
+                } catch (Exception e) {
106
+                    logger.error("", e);
107
+                    return new ReturnT(ReturnT.FAIL_CODE, e.getMessage());
96 108
                 }
109
+                jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), new GlueJobHandler(jobHandler, triggerParam.getGlueUpdatetime()));
97 110
             }
111
+
98 112
         }
99 113
 
100 114
         // push data to queue

+ 9 - 0
xxl-job-core/src/main/java/com/xxl/job/core/biz/model/TriggerParam.java View File

@@ -15,6 +15,7 @@ public class TriggerParam implements Serializable{
15 15
     private String executorParams;
16 16
 
17 17
     private boolean glueSwitch;
18
+    private long glueUpdatetime;
18 19
 
19 20
     private int logId;
20 21
     private long logDateTim;
@@ -53,6 +54,14 @@ public class TriggerParam implements Serializable{
53 54
         this.glueSwitch = glueSwitch;
54 55
     }
55 56
 
57
+    public long getGlueUpdatetime() {
58
+        return glueUpdatetime;
59
+    }
60
+
61
+    public void setGlueUpdatetime(long glueUpdatetime) {
62
+        this.glueUpdatetime = glueUpdatetime;
63
+    }
64
+
56 65
     public int getLogId() {
57 66
         return logId;
58 67
     }

+ 4 - 46
xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java View File

@@ -1,6 +1,5 @@
1 1
 package com.xxl.job.core.glue;
2 2
 
3
-import com.xxl.job.core.glue.cache.LocalCache;
4 3
 import com.xxl.job.core.glue.loader.GlueLoader;
5 4
 import com.xxl.job.core.handler.IJobHandler;
6 5
 import groovy.lang.GroovyClassLoader;
@@ -30,14 +29,6 @@ public class GlueFactory implements ApplicationContextAware {
30 29
 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
31 30
 	
32 31
 	/**
33
-	 * glue cache timeout / second
34
-	 */
35
-	private long cacheTimeout = 5000;
36
-	public void setCacheTimeout(long cacheTimeout) {
37
-		this.cacheTimeout = cacheTimeout;
38
-	}
39
-	
40
-	/**
41 32
 	 * code source loader
42 33
 	 */
43 34
 	private GlueLoader glueLoader;
@@ -51,6 +42,9 @@ public class GlueFactory implements ApplicationContextAware {
51 42
 	// ----------------------------- spring support -----------------------------
52 43
 	private static ApplicationContext applicationContext;
53 44
 	private static GlueFactory glueFactory;
45
+	public static GlueFactory getInstance(){
46
+		return glueFactory;
47
+	}
54 48
 	
55 49
 	@Override
56 50
 	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
@@ -134,41 +128,5 @@ public class GlueFactory implements ApplicationContextAware {
134 128
 		}
135 129
 		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadNewInstance error, instance is null");
136 130
 	}
137
-	
138
-	// // load instance, singleton
139
-	private static String generateInstanceCacheKey(int jobId){
140
-		return String.valueOf(jobId).concat("_instance");
141
-	}
142
-	public IJobHandler loadInstance(int jobId) throws Exception{
143
-		if (jobId==0) {
144
-			return null;
145
-		}
146
-		String cacheInstanceKey = generateInstanceCacheKey(jobId);
147
-		Object cacheInstance = LocalCache.getInstance().get(cacheInstanceKey);
148
-		if (cacheInstance!=null) {
149
-			if (!(cacheInstance instanceof IJobHandler)) {
150
-				throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, "
151
-						+ "cannot convert from cacheClass["+ cacheInstance.getClass() +"] to IJobHandler");
152
-			}
153
-			return (IJobHandler) cacheInstance;
154
-		}
155
-		Object instance = loadNewInstance(jobId);
156
-		if (instance!=null) {
157
-			if (!(instance instanceof IJobHandler)) {
158
-				throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, "
159
-						+ "cannot convert from instance["+ instance.getClass() +"] to IJobHandler");
160
-			}
161
-			
162
-			LocalCache.getInstance().set(cacheInstanceKey, instance, cacheTimeout);
163
-			logger.info(">>>>>>>>>>>> xxl-glue, fresh instance, cacheInstanceKey:{}", cacheInstanceKey);
164
-			return (IJobHandler) instance;
165
-		}
166
-		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, instance is null");
167
-	}
168
-	
169
-	// ----------------------------- util -----------------------------
170
-	public static void glue(int jobId, String... params) throws Exception{
171
-		GlueFactory.glueFactory.loadInstance(jobId).execute(params);
172
-	}
173
-	
131
+
174 132
 }

+ 0 - 17
xxl-job-core/src/main/java/com/xxl/job/core/glue/cache/ICache.java View File

@@ -1,17 +0,0 @@
1
-package com.xxl.job.core.glue.cache;
2
-
3
-/**
4
- * chche interface
5
- * @author xuxueli 2016-1-8 15:57:27
6
- */
7
-public interface ICache {
8
-	
9
-	public boolean set(String key, Object value);
10
-	
11
-	public boolean set(String key, Object value, long timeout);
12
-	
13
-	public Object get(String key);
14
-	
15
-	public boolean remove(String key);
16
-	
17
-}

+ 0 - 71
xxl-job-core/src/main/java/com/xxl/job/core/glue/cache/LocalCache.java View File

@@ -1,71 +0,0 @@
1
-package com.xxl.job.core.glue.cache;
2
-
3
-import java.util.concurrent.ConcurrentHashMap;
4
-
5
-/**
6
- * local interface
7
- * @author Administrator
8
- */
9
-public class LocalCache implements ICache{
10
-	
11
-	private static final LocalCache instance = new LocalCache();
12
-	public static LocalCache getInstance(){
13
-		return instance;
14
-	} 
15
-	
16
-	private static final ConcurrentHashMap<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();
17
-	private static final long CACHE_TIMEOUT = 5000;
18
-	
19
-	private static String makeTimKey(String key){
20
-		return key.concat("_tim");
21
-	}
22
-	private static String makeDataKey(String key){
23
-		return key.concat("_data");
24
-	}
25
-	
26
-	@Override
27
-	public boolean set(String key, Object value) {
28
-		cacheMap.put(makeTimKey(key), System.currentTimeMillis() + CACHE_TIMEOUT);
29
-		cacheMap.put(makeDataKey(key), value);
30
-		return true;
31
-	}
32
-	
33
-	@Override
34
-	public boolean set(String key, Object value, long timeout) {
35
-		cacheMap.put(makeTimKey(key), System.currentTimeMillis() + timeout);
36
-		cacheMap.put(makeDataKey(key), value);
37
-		return true;
38
-	}
39
-
40
-	@Override
41
-	public Object get(String key) {
42
-		Object tim = cacheMap.get(makeTimKey(key));
43
-		if (tim != null && System.currentTimeMillis() < Long.parseLong(tim.toString())) {
44
-			return cacheMap.get(makeDataKey(key));
45
-		}
46
-		return null;
47
-	}
48
-
49
-	@Override
50
-	public boolean remove(String key) {
51
-		cacheMap.remove(makeTimKey(key));
52
-		cacheMap.remove(makeDataKey(key));
53
-		return true;
54
-	}
55
-	
56
-	public static void main(String[] args) {
57
-		String key = "key01";
58
-		System.out.println(LocalCache.getInstance().get(key));
59
-		
60
-		LocalCache.getInstance().set(key, "v1");
61
-		System.out.println(LocalCache.getInstance().get(key));
62
-		
63
-		LocalCache.getInstance().set(key, "v2");
64
-		System.out.println(LocalCache.getInstance().get(key));
65
-		
66
-		LocalCache.getInstance().remove(key);
67
-		System.out.println(LocalCache.getInstance().get(key));
68
-		
69
-	}
70
-	
71
-}

+ 14 - 6
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/GlueJobHandler.java View File

@@ -1,22 +1,30 @@
1 1
 package com.xxl.job.core.handler.impl;
2 2
 
3
-import com.xxl.job.core.glue.GlueFactory;
4 3
 import com.xxl.job.core.handler.IJobHandler;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
5 6
 
6 7
 /**
7 8
  * glue job handler
8 9
  * @author xuxueli 2016-5-19 21:05:45
9 10
  */
10 11
 public class GlueJobHandler extends IJobHandler {
11
-	
12
-	private int jobId;
13
-	public GlueJobHandler(int jobId) {
14
-		this.jobId = jobId;
12
+	private static Logger logger = LoggerFactory.getLogger(GlueJobHandler.class);
13
+
14
+	private long glueUpdatetime;
15
+	private IJobHandler jobHandler;
16
+	public GlueJobHandler(IJobHandler jobHandler, long glueUpdatetime) {
17
+		this.jobHandler = jobHandler;
18
+		this.glueUpdatetime = glueUpdatetime;
19
+	}
20
+	public long getGlueUpdatetime() {
21
+		return glueUpdatetime;
15 22
 	}
16 23
 
17 24
 	@Override
18 25
 	public void execute(String... params) throws Exception {
19
-		GlueFactory.glue(jobId, params);
26
+		logger.info("----------- glue.version:{} -----------", glueUpdatetime);
27
+		jobHandler.execute(params);
20 28
 	}
21 29
 
22 30
 }

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

@@ -28,7 +28,7 @@ public class DemoJobHandler extends IJobHandler {
28 28
 	public void execute(String... params) throws Exception {
29 29
 		logger.info("XXL-JOB, Hello World.");
30 30
 		
31
-		for (int i = 0; i < 2; i++) {
31
+		for (int i = 0; i < 5; i++) {
32 32
 			logger.info("beat at:{}", i);
33 33
 			TimeUnit.SECONDS.sleep(2);
34 34
 		}

+ 0 - 2
xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml View File

@@ -42,8 +42,6 @@
42 42
 
43 43
 	<!-- 配置03、GlueFactory -->
44 44
 	<bean id="glueFactory" class="com.xxl.job.core.glue.GlueFactory">
45
-		<!-- GLUE任务示例缓存失效时间, 单位/ms -->
46
-		<property name="cacheTimeout" value="${xxl.job.glue.cache.time}" />
47 45
 		<!-- GLUE源码加载器,默认使用系统提供的 "DbGlueLoader", 推荐将其改为公共的RPC服务 -->
48 46
 		<property name="glueLoader" >
49 47
             <!-- DbGlueLoader, 依赖 "XXL-JOB公共数据源" -->

+ 1 - 4
xxl-job-executor-example/src/main/resources/xxl-job-executor.properties View File

@@ -7,7 +7,4 @@ xxl.job.db.password=root_pwd
7 7
 ### xxl-job executor address
8 8
 xxl.job.executor.appname=xxl-job-executor-example
9 9
 xxl.job.executor.ip=
10
-xxl.job.executor.port=9999
11
-
12
-### xxl-job glue cache time/ms
13
-xxl.job.glue.cache.time=10000
10
+xxl.job.executor.port=9999