Преглед на файлове

访问令牌(accessToken):为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;

xuxueli преди 8 години
родител
ревизия
1bc5cc76be
променени са 18 файла, в които са добавени 99 реда и са изтрити 26 реда
  1. 1 0
      doc/XXL-JOB官方文档.md
  2. 3 2
      xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
  3. 2 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java
  4. 2 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
  5. 2 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
  6. 12 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/schedule/XxlJobDynamicScheduler.java
  7. 1 0
      xxl-job-admin/src/main/resources/spring/applicationcontext-xxl-job-admin.xml
  8. 4 1
      xxl-job-admin/src/main/resources/xxl-job-admin.properties
  9. 2 1
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/AdminBizTest.java
  10. 10 4
      xxl-job-core/src/main/java/com/xxl/job/core/executor/XxlJobExecutor.java
  11. 30 7
      xxl-job-core/src/main/java/com/xxl/job/core/rpc/codec/RpcRequest.java
  12. 6 3
      xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComClientProxy.java
  13. 10 2
      xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComServerFactory.java
  14. 2 0
      xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml
  15. 4 1
      xxl-job-executor-example/src/main/resources/xxl-job-executor.properties
  16. 2 1
      xxl-job-executor-example/src/test/java/com/xxl/executor/test/DemoJobHandlerTest.java
  17. 3 0
      xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java
  18. 3 0
      xxl-job-executor-springboot-example/src/main/resources/application.properties

+ 1 - 0
doc/XXL-JOB官方文档.md Целия файл

@@ -905,6 +905,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
905 905
 - 6、调度中心API服务改为自研RPC形式,统一底层通讯模型;
906 906
 - 7、新增调度中心API服务测试Demo,方便在调度中心API扩展和测试;
907 907
 - 8、任务列表页交互优化,更换执行器分组时自动刷新任务列表,新建任务时默认定位在当前执行器位置;
908
+- 9、访问令牌(accessToken):为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;
908 909
 
909 910
 #### TODO LIST
910 911
 - 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;

+ 3 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java Целия файл

@@ -3,6 +3,7 @@ package com.xxl.job.admin.controller;
3 3
 import com.xxl.job.admin.core.model.XxlJobGroup;
4 4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5 5
 import com.xxl.job.admin.core.model.XxlJobLog;
6
+import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
6 7
 import com.xxl.job.admin.dao.XxlJobGroupDao;
7 8
 import com.xxl.job.admin.dao.XxlJobInfoDao;
8 9
 import com.xxl.job.admin.dao.XxlJobLogDao;
@@ -119,7 +120,7 @@ public class JobLogController {
119 120
 	@ResponseBody
120 121
 	public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, int logId, int fromLineNum){
121 122
 		try {
122
-			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, executorAddress).getObject();
123
+			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, executorAddress, XxlJobDynamicScheduler.getAccessToken()).getObject();
123 124
 			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
124 125
 
125 126
 			// is end
@@ -153,7 +154,7 @@ public class JobLogController {
153 154
 		// request of kill
154 155
 		ReturnT<String> runResult = null;
155 156
 		try {
156
-			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, log.getExecutorAddress()).getObject();
157
+			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, log.getExecutorAddress(), XxlJobDynamicScheduler.getAccessToken()).getObject();
157 158
 			runResult = executorBiz.kill(jobInfo.getId());
158 159
 		} catch (Exception e) {
159 160
 			logger.error(e.getMessage(), e);

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package com.xxl.job.admin.core.route;
2 2
 
3
+import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
3 4
 import com.xxl.job.core.biz.ExecutorBiz;
4 5
 import com.xxl.job.core.biz.model.ReturnT;
5 6
 import com.xxl.job.core.biz.model.TriggerParam;
@@ -33,7 +34,7 @@ public abstract class ExecutorRouter {
33 34
     public static ReturnT<String> runExecutor(TriggerParam triggerParam, String address){
34 35
         ReturnT<String> runResult = null;
35 36
         try {
36
-            ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
37
+            ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, XxlJobDynamicScheduler.getAccessToken()).getObject();
37 38
             runResult = executorBiz.run(triggerParam);
38 39
         } catch (Exception e) {
39 40
             logger.error(e.getMessage(), e);

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java Целия файл

@@ -1,6 +1,7 @@
1 1
 package com.xxl.job.admin.core.route.strategy;
2 2
 
3 3
 import com.xxl.job.admin.core.route.ExecutorRouter;
4
+import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
4 5
 import com.xxl.job.core.biz.ExecutorBiz;
5 6
 import com.xxl.job.core.biz.model.ReturnT;
6 7
 import com.xxl.job.core.biz.model.TriggerParam;
@@ -25,7 +26,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
25 26
             // beat
26 27
             ReturnT<String> idleBeatResult = null;
27 28
             try {
28
-                ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
29
+                ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, XxlJobDynamicScheduler.getAccessToken()).getObject();
29 30
                 idleBeatResult = executorBiz.idleBeat(triggerParam.getJobId());
30 31
             } catch (Exception e) {
31 32
                 logger.error(e.getMessage(), e);

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java Целия файл

@@ -1,6 +1,7 @@
1 1
 package com.xxl.job.admin.core.route.strategy;
2 2
 
3 3
 import com.xxl.job.admin.core.route.ExecutorRouter;
4
+import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
4 5
 import com.xxl.job.core.biz.ExecutorBiz;
5 6
 import com.xxl.job.core.biz.model.ReturnT;
6 7
 import com.xxl.job.core.biz.model.TriggerParam;
@@ -25,7 +26,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
25 26
             // beat
26 27
             ReturnT<String> beatResult = null;
27 28
             try {
28
-                ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address).getObject();
29
+                ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, XxlJobDynamicScheduler.getAccessToken()).getObject();
29 30
                 beatResult = executorBiz.beat();
30 31
             } catch (Exception e) {
31 32
                 logger.error(e.getMessage(), e);

+ 12 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/schedule/XxlJobDynamicScheduler.java Целия файл

@@ -36,7 +36,16 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
36 36
     public void setScheduler(Scheduler scheduler) {
37 37
 		XxlJobDynamicScheduler.scheduler = scheduler;
38 38
 	}
39
-    
39
+
40
+	// accessToken
41
+    private static String accessToken;
42
+    public void setAccessToken(String accessToken) {
43
+        this.accessToken = accessToken;
44
+    }
45
+    public static String getAccessToken() {
46
+        return accessToken;
47
+    }
48
+
40 49
     // init
41 50
     public void init() throws Exception {
42 51
 		// admin registry monitor run
@@ -47,6 +56,8 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware, In
47 56
 
48 57
         // rpc-service, base on spring-mvc
49 58
         NetComServerFactory.putService(AdminBiz.class, XxlJobDynamicScheduler.adminBiz);
59
+        NetComServerFactory.setAccessToken(accessToken);
60
+
50 61
     }
51 62
     
52 63
     // destroy

+ 1 - 0
xxl-job-admin/src/main/resources/spring/applicationcontext-xxl-job-admin.xml Целия файл

@@ -65,6 +65,7 @@
65 65
 	<bean id="xxlJobDynamicScheduler" class="com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler" init-method="init" destroy-method="destroy" >
66 66
 		<!-- (轻易不要变更“调度器名称”, 任务创建时会绑定该“调度器名称”) -->
67 67
 		<property name="scheduler" ref="quartzScheduler"/>
68
+		<property name="accessToken" value="${xxl.job.accessToken}" />
68 69
 	</bean>
69 70
 	
70 71
 </beans>

+ 4 - 1
xxl-job-admin/src/main/resources/xxl-job-admin.properties Целия файл

@@ -14,4 +14,7 @@ xxl.job.mail.sendNick=《任务调度平台XXL-JOB》
14 14
 
15 15
 # xxl-job login
16 16
 xxl.job.login.username=admin
17
-xxl.job.login.password=123456
17
+xxl.job.login.password=123456
18
+
19
+# xxl-job, access token
20
+xxl.job.accessToken=

+ 2 - 1
xxl-job-admin/src/test/java/com/xxl/job/dao/impl/AdminBizTest.java Целия файл

@@ -19,7 +19,8 @@ public class AdminBizTest {
19 19
 
20 20
         // admin-client
21 21
         String addressUrl = "http://127.0.0.1:8080/xxl-job-admin".concat(AdminBiz.MAPPING);
22
-        AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl).getObject();
22
+        String accessToken = null;
23
+        AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl, accessToken).getObject();
23 24
 
24 25
         // test executor registry
25 26
         RegistryParam registryParam = new RegistryParam(RegistryConfig.RegistType.EXECUTOR.name(), "xxl-job-executor-example", "127.0.0.1:9999");

+ 10 - 4
xxl-job-core/src/main/java/com/xxl/job/core/executor/XxlJobExecutor.java Целия файл

@@ -34,7 +34,8 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
34 34
     private int port = 9999;
35 35
     private String appName;
36 36
     private String adminAddresses;
37
-    public static String logPath;
37
+    private String accessToken;
38
+    public static String logPath = "/data/applogs/xxl-job/jobhandler/";
38 39
 
39 40
     public void setIp(String ip) {
40 41
         this.ip = ip;
@@ -48,18 +49,21 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
48 49
     public void setAdminAddresses(String adminAddresses) {
49 50
         this.adminAddresses = adminAddresses;
50 51
     }
52
+    public void setAccessToken(String accessToken) {
53
+        this.accessToken = accessToken;
54
+    }
51 55
     public void setLogPath(String logPath) {
52 56
         this.logPath = logPath;
53 57
     }
54 58
 
55 59
     // ---------------------------------- admin-client ------------------------------------
56 60
     private static List<AdminBiz> adminBizList;
57
-    private static void initAdminBizList(String adminAddresses) throws Exception {
61
+    private static void initAdminBizList(String adminAddresses, String accessToken) throws Exception {
58 62
         if (adminAddresses!=null && adminAddresses.trim().length()>0) {
59 63
             for (String address: adminAddresses.trim().split(",")) {
60 64
                 if (address!=null && address.trim().length()>0) {
61 65
                     String addressUrl = address.concat(AdminBiz.MAPPING);
62
-                    AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl).getObject();
66
+                    AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl, accessToken).getObject();
63 67
                     if (adminBizList == null) {
64 68
                         adminBizList = new ArrayList<AdminBiz>();
65 69
                     }
@@ -76,12 +80,14 @@ public class XxlJobExecutor implements ApplicationContextAware, ApplicationListe
76 80
     private NetComServerFactory serverFactory = new NetComServerFactory();
77 81
     public void start() throws Exception {
78 82
         // init admin-client
79
-        initAdminBizList(adminAddresses);
83
+        initAdminBizList(adminAddresses, accessToken);
80 84
 
81 85
         // executor start
82 86
         NetComServerFactory.putService(ExecutorBiz.class, new ExecutorBizImpl());   // rpc-service, base on jetty
87
+        NetComServerFactory.setAccessToken(accessToken);
83 88
         serverFactory.start(port, ip, appName);
84 89
 
90
+
85 91
         // trigger callback thread start
86 92
         TriggerCallbackThread.getInstance().start();
87 93
     }

+ 30 - 7
xxl-job-core/src/main/java/com/xxl/job/core/rpc/codec/RpcRequest.java Целия файл

@@ -12,12 +12,14 @@ public class RpcRequest implements Serializable{
12 12
 	
13 13
 	private String serverAddress;
14 14
 	private long createMillisTime;
15
+	private String accessToken;
15 16
 
16 17
     private String className;
17 18
     private String methodName;
18 19
     private Class<?>[] parameterTypes;
19 20
     private Object[] parameters;
20 21
 
22
+
21 23
 	public String getServerAddress() {
22 24
 		return serverAddress;
23 25
 	}
@@ -29,41 +31,62 @@ public class RpcRequest implements Serializable{
29 31
 	public long getCreateMillisTime() {
30 32
 		return createMillisTime;
31 33
 	}
34
+
32 35
 	public void setCreateMillisTime(long createMillisTime) {
33 36
 		this.createMillisTime = createMillisTime;
34 37
 	}
38
+
39
+	public String getAccessToken() {
40
+		return accessToken;
41
+	}
42
+
43
+	public void setAccessToken(String accessToken) {
44
+		this.accessToken = accessToken;
45
+	}
46
+
35 47
 	public String getClassName() {
36 48
 		return className;
37 49
 	}
50
+
38 51
 	public void setClassName(String className) {
39 52
 		this.className = className;
40 53
 	}
54
+
41 55
 	public String getMethodName() {
42 56
 		return methodName;
43 57
 	}
58
+
44 59
 	public void setMethodName(String methodName) {
45 60
 		this.methodName = methodName;
46 61
 	}
62
+
47 63
 	public Class<?>[] getParameterTypes() {
48 64
 		return parameterTypes;
49 65
 	}
66
+
50 67
 	public void setParameterTypes(Class<?>[] parameterTypes) {
51 68
 		this.parameterTypes = parameterTypes;
52 69
 	}
70
+
53 71
 	public Object[] getParameters() {
54 72
 		return parameters;
55 73
 	}
74
+
56 75
 	public void setParameters(Object[] parameters) {
57 76
 		this.parameters = parameters;
58 77
 	}
59
-	
78
+
60 79
 	@Override
61 80
 	public String toString() {
62
-		return "NettyRequest [serverAddress=" + serverAddress + ", createMillisTime="
63
-				+ createMillisTime + ", className=" + className
64
-				+ ", methodName=" + methodName + ", parameterTypes="
65
-				+ Arrays.toString(parameterTypes) + ", parameters="
66
-				+ Arrays.toString(parameters) + "]";
81
+		return "RpcRequest{" +
82
+				"serverAddress='" + serverAddress + '\'' +
83
+				", createMillisTime=" + createMillisTime +
84
+				", accessToken='" + accessToken + '\'' +
85
+				", className='" + className + '\'' +
86
+				", methodName='" + methodName + '\'' +
87
+				", parameterTypes=" + Arrays.toString(parameterTypes) +
88
+				", parameters=" + Arrays.toString(parameters) +
89
+				'}';
67 90
 	}
68
-	
91
+
69 92
 }

+ 6 - 3
xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComClientProxy.java Целия файл

@@ -20,11 +20,13 @@ public class NetComClientProxy implements FactoryBean<Object> {
20 20
 
21 21
 	// ---------------------- config ----------------------
22 22
 	private Class<?> iface;
23
-	String serverAddress;
24
-	JettyClient client = new JettyClient();
25
-	public NetComClientProxy(Class<?> iface, String serverAddress) {
23
+	private String serverAddress;
24
+	private String accessToken;
25
+	private JettyClient client = new JettyClient();
26
+	public NetComClientProxy(Class<?> iface, String serverAddress, String accessToken) {
26 27
 		this.iface = iface;
27 28
 		this.serverAddress = serverAddress;
29
+		this.accessToken = accessToken;
28 30
 	}
29 31
 
30 32
 	@Override
@@ -39,6 +41,7 @@ public class NetComClientProxy implements FactoryBean<Object> {
39 41
 						RpcRequest request = new RpcRequest();
40 42
 	                    request.setServerAddress(serverAddress);
41 43
 	                    request.setCreateMillisTime(System.currentTimeMillis());
44
+	                    request.setAccessToken(accessToken);
42 45
 	                    request.setClassName(method.getDeclaringClass().getName());
43 46
 	                    request.setMethodName(method.getName());
44 47
 	                    request.setParameterTypes(method.getParameterTypes());

+ 10 - 2
xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComServerFactory.java Целия файл

@@ -30,14 +30,18 @@ public class NetComServerFactory  {
30 30
 		server.destroy();
31 31
 	}
32 32
 
33
-	// ---------------------- server init ----------------------
33
+	// ---------------------- server instance ----------------------
34 34
 	/**
35 35
 	 * init local rpc service map
36 36
 	 */
37 37
 	private static Map<String, Object> serviceMap = new HashMap<String, Object>();
38
+	private static String accessToken;
38 39
 	public static void putService(Class<?> iface, Object serviceBean){
39 40
 		serviceMap.put(iface.getName(), serviceBean);
40 41
 	}
42
+	public static void setAccessToken(String accessToken) {
43
+		NetComServerFactory.accessToken = accessToken;
44
+	}
41 45
 	public static RpcResponse invokeService(RpcRequest request, Object serviceBean) {
42 46
 		if (serviceBean==null) {
43 47
 			serviceBean = serviceMap.get(request.getClassName());
@@ -49,7 +53,11 @@ public class NetComServerFactory  {
49 53
 		RpcResponse response = new RpcResponse();
50 54
 
51 55
 		if (System.currentTimeMillis() - request.getCreateMillisTime() > 180000) {
52
-			response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "the timestamp difference between admin and executor exceeds the limit."));
56
+			response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The timestamp difference between admin and executor exceeds the limit."));
57
+			return response;
58
+		}
59
+		if (accessToken!=null && accessToken.trim().length()>0 && !accessToken.trim().equals(request.getAccessToken())) {
60
+			response.setResult(new ReturnT<String>(ReturnT.FAIL_CODE, "The access token[" + request.getAccessToken() + "] is wrong."));
53 61
 			return response;
54 62
 		}
55 63
 

+ 2 - 0
xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml Целия файл

@@ -33,6 +33,8 @@
33 33
 		<property name="adminAddresses" value="${xxl.job.admin.addresses}" />
34 34
 		<!-- 执行器日志路径[必填] -->
35 35
 		<property name="logPath" value="${xxl.job.executor.logpath}" />
36
+		<!-- 访问令牌,非空则进行匹配校验[选填] -->
37
+		<property name="accessToken" value="${xxl.job.accessToken}" />
36 38
 	</bean>
37 39
 
38 40
 

+ 4 - 1
xxl-job-executor-example/src/main/resources/xxl-job-executor.properties Целия файл

@@ -7,4 +7,7 @@ xxl.job.executor.ip=
7 7
 xxl.job.executor.port=9999
8 8
 
9 9
 ### xxl-job log path
10
-xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
10
+xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
11
+
12
+### xxl-job, access token
13
+xxl.job.accessToken=

+ 2 - 1
xxl-job-executor-example/src/test/java/com/xxl/executor/test/DemoJobHandlerTest.java Целия файл

@@ -33,7 +33,8 @@ public class DemoJobHandlerTest {
33 33
         triggerParam.setLogDateTim(System.currentTimeMillis());
34 34
 
35 35
         // do remote trigger
36
-        ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, "127.0.0.1:9999").getObject();
36
+        String accessToken = null;
37
+        ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, "127.0.0.1:9999", null).getObject();
37 38
         ReturnT<String> runResult = executorBiz.run(triggerParam);
38 39
     }
39 40
 

+ 3 - 0
xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java Целия файл

@@ -34,6 +34,8 @@ public class XxlJobConfig {
34 34
     @Value("${xxl.job.executor.logpath}")
35 35
     private String logpath;
36 36
 
37
+    @Value("${xxl.job.accessToken}")
38
+    private String accessToken;
37 39
 
38 40
     @Bean(initMethod = "start", destroyMethod = "destroy")
39 41
     public XxlJobExecutor xxlJobExecutor() {
@@ -44,6 +46,7 @@ public class XxlJobConfig {
44 46
         xxlJobExecutor.setAppName(appname);
45 47
         xxlJobExecutor.setAdminAddresses(addresses);
46 48
         xxlJobExecutor.setLogPath(logpath);
49
+        xxlJobExecutor.setAccessToken(accessToken);
47 50
         return xxlJobExecutor;
48 51
     }
49 52
 

+ 3 - 0
xxl-job-executor-springboot-example/src/main/resources/application.properties Целия файл

@@ -15,3 +15,6 @@ xxl.job.executor.port=9998
15 15
 
16 16
 ### xxl-job log path
17 17
 xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/
18
+
19
+### xxl-job, access token
20
+xxl.job.accessToken=