Bladeren bron

阻塞处理策略

xueli.xue 8 jaren geleden
bovenliggende
commit
744c00494b

+ 1 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/biz/AdminBizImpl.java Bestand weergeven

@@ -69,7 +69,7 @@ public class AdminBizImpl implements AdminBiz {
69 69
             handleMsg.append(log.getHandleMsg()).append("<br>");
70 70
         }
71 71
         if (handleCallbackParam.getExecuteResult().getMsg() != null) {
72
-            handleMsg.append("执行备注:").append(handleCallbackParam.getExecuteResult().getMsg());
72
+            handleMsg.append(handleCallbackParam.getExecuteResult().getMsg());
73 73
         }
74 74
         if (childTriggerMsg !=null) {
75 75
             handleMsg.append("<br>子任务触发备注:").append(childTriggerMsg);

+ 59 - 41
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java Bestand weergeven

@@ -33,12 +33,8 @@ public class ExecutorBizImpl implements ExecutorBiz {
33 33
     public ReturnT<String> kill(int jobId) {
34 34
         // kill handlerThread, and create new one
35 35
         JobThread jobThread = XxlJobExecutor.loadJobThread(jobId);
36
-
37 36
         if (jobThread != null) {
38
-            IJobHandler handler = jobThread.getHandler();
39
-            jobThread.toStop("人工手动终止");
40
-            jobThread.interrupt();
41
-            XxlJobExecutor.removeJobThread(jobId);
37
+            XxlJobExecutor.removeJobThread(jobId, "人工手动终止");
42 38
             return ReturnT.SUCCESS;
43 39
         }
44 40
 
@@ -56,81 +52,103 @@ public class ExecutorBizImpl implements ExecutorBiz {
56 52
 
57 53
     @Override
58 54
     public ReturnT<String> run(TriggerParam triggerParam) {
59
-        // load old thread
55
+        // load old:jobHandler + jobThread
60 56
         JobThread jobThread = XxlJobExecutor.loadJobThread(triggerParam.getJobId());
57
+        IJobHandler jobHandler = jobThread!=null?jobThread.getHandler():null;
58
+        String removeOldReason = null;
61 59
 
60
+        // valid:jobHandler + jobThread
62 61
         if (GlueTypeEnum.BEAN==GlueTypeEnum.match(triggerParam.getGlueType())) {
63 62
 
64
-            // valid handler
65
-            IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());
66
-            if (jobHandler==null) {
67
-                return new ReturnT<String>(ReturnT.FAIL_CODE, "job handler [" + triggerParam.getExecutorHandler() + "] not found.");
68
-            }
63
+            // valid old jobThread
64
+            if (jobThread != null && jobHandler!=null && jobThread.getHandler() != jobHandler) {
65
+                // change handler, need kill old thread
66
+                removeOldReason = "更新JobHandler或更换任务模式,终止旧任务线程";
69 67
 
70
-            // valid exists job thread:change handler, need kill old thread
71
-            if (jobThread != null && jobThread.getHandler() != jobHandler) {
72
-                // kill old job thread
73
-                jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
74
-                jobThread.interrupt();
75
-                XxlJobExecutor.removeJobThread(triggerParam.getJobId());
76 68
                 jobThread = null;
69
+                jobHandler = null;
77 70
             }
78 71
 
79
-            // make thread: new or exists invalid
80
-            if (jobThread == null) {
81
-                jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), jobHandler);
72
+            // valid handler
73
+            if (jobHandler == null) {
74
+                jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());
75
+                if (jobHandler == null) {
76
+                    return new ReturnT<String>(ReturnT.FAIL_CODE, "job handler [" + triggerParam.getExecutorHandler() + "] not found.");
77
+                }
82 78
             }
83 79
 
84 80
         } else if (GlueTypeEnum.GLUE_GROOVY==GlueTypeEnum.match(triggerParam.getGlueType())) {
85 81
 
86
-            // valid exists job thread:change handler or gluesource updated, need kill old thread
82
+            // valid old jobThread
87 83
             if (jobThread != null &&
88 84
                     !(jobThread.getHandler() instanceof GlueJobHandler
89 85
                         && ((GlueJobHandler) jobThread.getHandler()).getGlueUpdatetime()==triggerParam.getGlueUpdatetime() )) {
90
-                // change glue model or gluesource updated, kill old job thread
91
-                jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
92
-                jobThread.interrupt();
93
-                XxlJobExecutor.removeJobThread(triggerParam.getJobId());
86
+                // change handler or gluesource updated, need kill old thread
87
+                removeOldReason = "更新任务逻辑或更换任务模式,终止旧任务线程";
88
+
94 89
                 jobThread = null;
90
+                jobHandler = null;
95 91
             }
96 92
 
97
-            // make thread: new or exists invalid
98
-            if (jobThread == null) {
99
-                IJobHandler jobHandler = null;
93
+            // valid handler
94
+            if (jobHandler == null) {
100 95
                 try {
101
-                    jobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource());
96
+                    IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource());
97
+                    jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime());
102 98
                 } catch (Exception e) {
103 99
                     logger.error("", e);
104 100
                     return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage());
105 101
                 }
106
-                jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), new GlueJobHandler(jobHandler, triggerParam.getGlueUpdatetime()));
107 102
             }
108 103
         } else if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(triggerParam.getGlueType())
109 104
                 || GlueTypeEnum.GLUE_PYTHON==GlueTypeEnum.match(triggerParam.getGlueType()) ) {
110 105
 
111
-            // valid exists job thread:change script or gluesource updated, need kill old thread
106
+            // valid old jobThread
112 107
             if (jobThread != null &&
113 108
                     !(jobThread.getHandler() instanceof ScriptJobHandler
114 109
                             && ((ScriptJobHandler) jobThread.getHandler()).getGlueUpdatetime()==triggerParam.getGlueUpdatetime() )) {
115
-                // change glue model or gluesource updated, kill old job thread
116
-                jobThread.toStop("更换任务模式或JobHandler,终止旧任务线程");
117
-                jobThread.interrupt();
118
-                XxlJobExecutor.removeJobThread(triggerParam.getJobId());
110
+                // change script or gluesource updated, need kill old thread
111
+                removeOldReason = "更新任务逻辑或更换任务模式,终止旧任务线程";
112
+
119 113
                 jobThread = null;
114
+                jobHandler = null;
120 115
             }
121 116
 
122
-            // make thread: new or exists invalid
123
-            if (jobThread == null) {
124
-                ScriptJobHandler scriptJobHandler = new ScriptJobHandler(triggerParam.getJobId(), triggerParam.getGlueUpdatetime(), triggerParam.getGlueSource(), GlueTypeEnum.match(triggerParam.getGlueType()));
125
-                jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), scriptJobHandler);
117
+            // valid handler
118
+            if (jobHandler == null) {
119
+                jobHandler = new ScriptJobHandler(triggerParam.getJobId(), triggerParam.getGlueUpdatetime(), triggerParam.getGlueSource(), GlueTypeEnum.match(triggerParam.getGlueType()));
126 120
             }
127 121
         } else {
128 122
             return new ReturnT<String>(ReturnT.FAIL_CODE, "glueType[" + triggerParam.getGlueType() + "] is not valid.");
129 123
         }
130 124
 
125
+        // executor block strategy
126
+        if (jobThread != null) {
127
+            ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(triggerParam.getExecutorBlockStrategy(), null);
128
+            if (ExecutorBlockStrategyEnum.DISCARD_LATER == blockStrategy) {
129
+                // discard when running
130
+                if (jobThread.isRunningOrHasQueue()) {
131
+                    return new ReturnT<String>(ReturnT.FAIL_CODE, "阻塞处理策略-生效:"+ExecutorBlockStrategyEnum.DISCARD_LATER.getTitle());
132
+                }
133
+            } else if (ExecutorBlockStrategyEnum.COVER_EARLY == blockStrategy) {
134
+                // kill running jobThread
135
+                if (jobThread.isRunningOrHasQueue()) {
136
+                    removeOldReason = "阻塞处理策略-生效:" + ExecutorBlockStrategyEnum.COVER_EARLY.getTitle();
137
+
138
+                    jobThread = null;
139
+                }
140
+            } else {
141
+                // just queue trigger
142
+            }
143
+        }
144
+
145
+        // replace thread (new or exists invalid)
146
+        if (jobThread == null) {
147
+            jobThread = XxlJobExecutor.registJobThread(triggerParam.getJobId(), jobHandler, removeOldReason);
148
+        }
149
+
131 150
         // push data to queue
132
-        ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(triggerParam.getExecutorBlockStrategy(), null);
133
-        ReturnT<String> pushResult = jobThread.pushTriggerQueue(triggerParam, blockStrategy);
151
+        ReturnT<String> pushResult = jobThread.pushTriggerQueue(triggerParam);
134 152
         return pushResult;
135 153
     }
136 154
 

+ 18 - 8
xxl-job-core/src/main/java/com/xxl/job/core/executor/XxlJobExecutor.java Bestand weergeven

@@ -121,19 +121,29 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
121 121
 
122 122
     // ---------------------------------- job thread repository
123 123
     private static ConcurrentHashMap<Integer, JobThread> JobThreadRepository = new ConcurrentHashMap<Integer, JobThread>();
124
-    public static JobThread registJobThread(int jobId, IJobHandler handler){
125
-        JobThread jobThread = new JobThread(handler);
126
-        jobThread.start();
124
+    public static JobThread registJobThread(int jobId, IJobHandler handler, String removeOldReason){
125
+        JobThread newJobThread = new JobThread(handler);
126
+        newJobThread.start();
127 127
         logger.info(">>>>>>>>>>> xxl-job regist JobThread success, jobId:{}, handler:{}", new Object[]{jobId, handler});
128
-        JobThreadRepository.put(jobId, jobThread);	// putIfAbsent | oh my god, map's put method return the old value!!!
129
-        return jobThread;
128
+
129
+        JobThread oldJobThread = JobThreadRepository.put(jobId, newJobThread);	// putIfAbsent | oh my god, map's put method return the old value!!!
130
+        if (oldJobThread != null) {
131
+            oldJobThread.toStop(removeOldReason);
132
+            oldJobThread.interrupt();
133
+        }
134
+
135
+        return newJobThread;
136
+    }
137
+    public static void removeJobThread(int jobId, String removeOldReason){
138
+        JobThread oldJobThread = JobThreadRepository.remove(jobId);
139
+        if (oldJobThread != null) {
140
+            oldJobThread.toStop(removeOldReason);
141
+            oldJobThread.interrupt();
142
+        }
130 143
     }
131 144
     public static JobThread loadJobThread(int jobId){
132 145
         JobThread jobThread = JobThreadRepository.get(jobId);
133 146
         return jobThread;
134 147
     }
135
-    public static void removeJobThread(int jobId){
136
-        JobThreadRepository.remove(jobId);
137
-    }
138 148
 
139 149
 }

+ 21 - 21
xxl-job-core/src/main/java/com/xxl/job/core/thread/JobThread.java Bestand weergeven

@@ -3,7 +3,6 @@ package com.xxl.job.core.thread;
3 3
 import com.xxl.job.core.biz.model.HandleCallbackParam;
4 4
 import com.xxl.job.core.biz.model.ReturnT;
5 5
 import com.xxl.job.core.biz.model.TriggerParam;
6
-import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
7 6
 import com.xxl.job.core.handler.IJobHandler;
8 7
 import com.xxl.job.core.log.XxlJobFileAppender;
9 8
 import com.xxl.job.core.log.XxlJobLogger;
@@ -32,7 +31,7 @@ public class JobThread extends Thread{
32 31
 	private boolean toStop = false;
33 32
 	private String stopReason;
34 33
 
35
-    private boolean running = false;
34
+    private boolean running = false;    // if running job
36 35
 
37 36
 
38 37
 	public JobThread(IJobHandler handler) {
@@ -44,35 +43,29 @@ public class JobThread extends Thread{
44 43
 		return handler;
45 44
 	}
46 45
 
47
-	public ReturnT<String> pushTriggerQueue(TriggerParam triggerParam, ExecutorBlockStrategyEnum blockStrategy) {
46
+    /**
47
+     * new trigger to queue
48
+     *
49
+     * @param triggerParam
50
+     * @return
51
+     */
52
+	public ReturnT<String> pushTriggerQueue(TriggerParam triggerParam) {
48 53
 		// avoid repeat
49 54
 		if (triggerLogIdSet.contains(triggerParam.getLogId())) {
50 55
 			logger.debug("repeate trigger job, logId:{}", triggerParam.getLogId());
51 56
 			return new ReturnT<String>(ReturnT.FAIL_CODE, "repeate trigger job, logId:" + triggerParam.getLogId());
52 57
 		}
53 58
 
54
-		// block strategy
55
-		if (ExecutorBlockStrategyEnum.DISCARD_LATER == blockStrategy) {
56
-            // discard when running
57
-            if (running) {
58
-                return new ReturnT<String>(ReturnT.FAIL_CODE, "任务阻塞:"+ExecutorBlockStrategyEnum.DISCARD_LATER.getTitle());
59
-            }
60
-		} else if (ExecutorBlockStrategyEnum.COVER_EARLY == blockStrategy) {
61
-            // kill running old and clear queue
62
-            if (running) {
63
-                this.interrupt();
64
-            }
65
-            triggerQueue.clear();
66
-            triggerLogIdSet.clear();
67
-		} else {
68
-            // just add to queue
69
-		}
70
-
71 59
 		triggerLogIdSet.add(triggerParam.getLogId());
72 60
 		triggerQueue.add(triggerParam);
73 61
         return ReturnT.SUCCESS;
74 62
 	}
75 63
 
64
+    /**
65
+     * kill job thread
66
+     *
67
+     * @param stopReason
68
+     */
76 69
 	public void toStop(String stopReason) {
77 70
 		/**
78 71
 		 * Thread.interrupt只支持终止线程的阻塞状态(wait、join、sleep),
@@ -83,8 +76,15 @@ public class JobThread extends Thread{
83 76
 		this.stopReason = stopReason;
84 77
 	}
85 78
 
79
+    /**
80
+     * is running job
81
+     * @return
82
+     */
83
+    public boolean isRunningOrHasQueue() {
84
+        return running || triggerQueue.size()>0;
85
+    }
86 86
 
87
-	@Override
87
+    @Override
88 88
 	public void run() {
89 89
 		while(!toStop){
90 90
 			running = false;