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
 		triggerParam.setExecutorHandler(jobInfo.getExecutorHandler());
60
 		triggerParam.setExecutorHandler(jobInfo.getExecutorHandler());
61
 		triggerParam.setExecutorParams(jobInfo.getExecutorParam());
61
 		triggerParam.setExecutorParams(jobInfo.getExecutorParam());
62
 		triggerParam.setGlueSwitch((jobInfo.getGlueSwitch()==0)?false:true);
62
 		triggerParam.setGlueSwitch((jobInfo.getGlueSwitch()==0)?false:true);
63
+		triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
63
 		triggerParam.setLogId(jobLog.getId());
64
 		triggerParam.setLogId(jobLog.getId());
64
 		triggerParam.setLogDateTim(jobLog.getTriggerTime().getTime());
65
 		triggerParam.setLogDateTim(jobLog.getTriggerTime().getTime());
65
 		triggerParam.setLogAddress(findCallbackAddressList());		// callback address list
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
 import com.xxl.job.core.handler.impl.GlueJobHandler;
9
 import com.xxl.job.core.handler.impl.GlueJobHandler;
10
 import com.xxl.job.core.log.XxlJobFileAppender;
10
 import com.xxl.job.core.log.XxlJobFileAppender;
11
 import com.xxl.job.core.thread.JobThread;
11
 import com.xxl.job.core.thread.JobThread;
12
+import org.slf4j.Logger;
13
+import org.slf4j.LoggerFactory;
12
 
14
 
13
 import java.util.Date;
15
 import java.util.Date;
14
 
16
 
16
  * Created by xuxueli on 17/3/1.
18
  * Created by xuxueli on 17/3/1.
17
  */
19
  */
18
 public class ExecutorBizImpl implements ExecutorBiz {
20
 public class ExecutorBizImpl implements ExecutorBiz {
21
+    private static Logger logger = LoggerFactory.getLogger(ExecutorBizImpl.class);
19
 
22
 
20
     @Override
23
     @Override
21
     public ReturnT<String> beat() {
24
     public ReturnT<String> beat() {
55
         if (!triggerParam.isGlueSwitch()) {
58
         if (!triggerParam.isGlueSwitch()) {
56
             // bean model
59
             // bean model
57
 
60
 
58
-            // valid handler instance
61
+            // valid handler
59
             IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());
62
             IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());
60
             if (jobHandler==null) {
63
             if (jobHandler==null) {
61
                 return new ReturnT(ReturnT.FAIL_CODE, "job handler for JobId=[" + triggerParam.getJobId() + "] not found.");
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
             if (jobThread == null) {
77
             if (jobThread == null) {
65
                 jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), jobHandler);
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
         } else {
81
         } else {
78
             // glue model
82
             // glue model
79
 
83
 
82
                 return new ReturnT(ReturnT.FAIL_CODE, "glueLoader for JobId=[" + triggerParam.getJobId() + "] not found.");
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
             if (jobThread == null) {
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
         // push data to queue
114
         // push data to queue

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

15
     private String executorParams;
15
     private String executorParams;
16
 
16
 
17
     private boolean glueSwitch;
17
     private boolean glueSwitch;
18
+    private long glueUpdatetime;
18
 
19
 
19
     private int logId;
20
     private int logId;
20
     private long logDateTim;
21
     private long logDateTim;
53
         this.glueSwitch = glueSwitch;
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
     public int getLogId() {
65
     public int getLogId() {
57
         return logId;
66
         return logId;
58
     }
67
     }

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

1
 package com.xxl.job.core.glue;
1
 package com.xxl.job.core.glue;
2
 
2
 
3
-import com.xxl.job.core.glue.cache.LocalCache;
4
 import com.xxl.job.core.glue.loader.GlueLoader;
3
 import com.xxl.job.core.glue.loader.GlueLoader;
5
 import com.xxl.job.core.handler.IJobHandler;
4
 import com.xxl.job.core.handler.IJobHandler;
6
 import groovy.lang.GroovyClassLoader;
5
 import groovy.lang.GroovyClassLoader;
30
 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
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
 	 * code source loader
32
 	 * code source loader
42
 	 */
33
 	 */
43
 	private GlueLoader glueLoader;
34
 	private GlueLoader glueLoader;
51
 	// ----------------------------- spring support -----------------------------
42
 	// ----------------------------- spring support -----------------------------
52
 	private static ApplicationContext applicationContext;
43
 	private static ApplicationContext applicationContext;
53
 	private static GlueFactory glueFactory;
44
 	private static GlueFactory glueFactory;
45
+	public static GlueFactory getInstance(){
46
+		return glueFactory;
47
+	}
54
 	
48
 	
55
 	@Override
49
 	@Override
56
 	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
50
 	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
134
 		}
128
 		}
135
 		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadNewInstance error, instance is null");
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
-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
-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
 package com.xxl.job.core.handler.impl;
1
 package com.xxl.job.core.handler.impl;
2
 
2
 
3
-import com.xxl.job.core.glue.GlueFactory;
4
 import com.xxl.job.core.handler.IJobHandler;
3
 import com.xxl.job.core.handler.IJobHandler;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
5
 
6
 
6
 /**
7
 /**
7
  * glue job handler
8
  * glue job handler
8
  * @author xuxueli 2016-5-19 21:05:45
9
  * @author xuxueli 2016-5-19 21:05:45
9
  */
10
  */
10
 public class GlueJobHandler extends IJobHandler {
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
 	@Override
24
 	@Override
18
 	public void execute(String... params) throws Exception {
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
 	public void execute(String... params) throws Exception {
28
 	public void execute(String... params) throws Exception {
29
 		logger.info("XXL-JOB, Hello World.");
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
 			logger.info("beat at:{}", i);
32
 			logger.info("beat at:{}", i);
33
 			TimeUnit.SECONDS.sleep(2);
33
 			TimeUnit.SECONDS.sleep(2);
34
 		}
34
 		}

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

42
 
42
 
43
 	<!-- 配置03、GlueFactory -->
43
 	<!-- 配置03、GlueFactory -->
44
 	<bean id="glueFactory" class="com.xxl.job.core.glue.GlueFactory">
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
 		<!-- GLUE源码加载器,默认使用系统提供的 "DbGlueLoader", 推荐将其改为公共的RPC服务 -->
45
 		<!-- GLUE源码加载器,默认使用系统提供的 "DbGlueLoader", 推荐将其改为公共的RPC服务 -->
48
 		<property name="glueLoader" >
46
 		<property name="glueLoader" >
49
             <!-- DbGlueLoader, 依赖 "XXL-JOB公共数据源" -->
47
             <!-- DbGlueLoader, 依赖 "XXL-JOB公共数据源" -->

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

7
 ### xxl-job executor address
7
 ### xxl-job executor address
8
 xxl.job.executor.appname=xxl-job-executor-example
8
 xxl.job.executor.appname=xxl-job-executor-example
9
 xxl.job.executor.ip=
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