瀏覽代碼

Merge branch 'master' into feature/timeout

许雪里 7 年之前
父節點
當前提交
c3c7ded5e0
沒有帳戶連結到提交者的電子郵件
共有 59 個文件被更改,包括 393 次插入159 次删除
  1. 30 0
      README.md
  2. 59 35
      doc/XXL-JOB-English-Documentation.md
  3. 111 39
      doc/XXL-JOB官方文档.md
  4. 4 3
      doc/db/tables_xxl_job.sql
  5. 二進制
      doc/images/img_6yC0.png
  6. 二進制
      doc/images/img_9235.png
  7. 二進制
      doc/images/img_BPLG.png
  8. 二進制
      doc/images/img_EB65.png
  9. 二進制
      doc/images/img_Fgql.png
  10. 二進制
      doc/images/img_Hr2T.png
  11. 二進制
      doc/images/img_Qohm.png
  12. 二進制
      doc/images/img_UDSo.png
  13. 二進制
      doc/images/img_V3vF.png
  14. 二進制
      doc/images/img_Wb2o.png
  15. 二進制
      doc/images/img_Ypik.png
  16. 二進制
      doc/images/img_Z5wp.png
  17. 二進制
      doc/images/img_Z9Qr.png
  18. 二進制
      doc/images/img_ZAhX.png
  19. 二進制
      doc/images/img_ZAsz.png
  20. 二進制
      doc/images/img_bNwm.png
  21. 二進制
      doc/images/img_dNUJ.png
  22. 二進制
      doc/images/img_eYrv.png
  23. 二進制
      doc/images/img_hIci.png
  24. 二進制
      doc/images/img_iUw0.png
  25. 二進制
      doc/images/img_inc8.png
  26. 二進制
      doc/images/img_jOAU.png
  27. 二進制
      doc/images/img_jrdI.png
  28. 二進制
      doc/images/img_o8HQ.png
  29. 二進制
      doc/images/img_oLlM.png
  30. 二進制
      doc/images/img_tJOq.png
  31. 二進制
      doc/images/img_tvGI.png
  32. 7 0
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
  33. 11 0
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/schedule/XxlJobDynamicScheduler.java
  34. 5 5
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java
  35. 1 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/I18nUtil.java
  36. 2 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/LocalCacheUtil.java
  37. 8 2
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/MailUtil.java
  38. 4 5
      xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
  39. 3 0
      xxl-job-admin/src/main/resources/i18n/message.properties
  40. 3 0
      xxl-job-admin/src/main/resources/i18n/message_en.properties
  41. 17 11
      xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml
  42. 1 0
      xxl-job-admin/src/main/resources/xxl-job-admin.properties
  43. 2 2
      xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl
  44. 1 1
      xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js
  45. 1 1
      xxl-job-admin/src/test/java/com/xxl/job/admin/util/MailUtilTest.java
  46. 8 0
      xxl-job-core/src/main/java/com/xxl/job/core/biz/AdminBiz.java
  47. 14 1
      xxl-job-core/src/main/java/com/xxl/job/core/biz/model/HandleCallbackParam.java
  48. 8 4
      xxl-job-core/src/main/java/com/xxl/job/core/enums/ExecutorBlockStrategyEnum.java
  49. 5 5
      xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueTypeEnum.java
  50. 12 3
      xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/ScriptJobHandler.java
  51. 13 15
      xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java
  52. 8 4
      xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobLogger.java
  53. 1 2
      xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComClientProxy.java
  54. 2 2
      xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/jetty/client/JettyClient.java
  55. 14 8
      xxl-job-core/src/main/java/com/xxl/job/core/thread/JobThread.java
  56. 17 4
      xxl-job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java
  57. 3 4
      xxl-job-core/src/main/java/com/xxl/job/core/util/HttpClientUtil.java
  58. 17 1
      xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java
  59. 1 0
      xxl-job-executor-samples/xxl-job-executor-sample-springboot/pom.xml

+ 30 - 0
README.md 查看文件

@@ -156,6 +156,36 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
156 156
     - 64、未来无线网
157 157
     - 65、厦门瓷禧网络有限公司
158 158
     - 66、北京递蓝科软件股份有限公司
159
+    - 67、郑州创海软件科技公司
160
+    - 68、北京国槐信息科技有限公司
161
+    - 69、浪潮软件集团
162
+    - 70、多立恒(北京)信息技术有限公司
163
+    - 71、广州极迅客信息科技有限公司
164
+    - 72、赫基(中国)集团股份有限公司
165
+    - 73、海投汇
166
+    - 74、上海润益创业孵化器管理股份有限公司
167
+    - 75、汉纳森(厦门)数据股份有限公司
168
+    - 76、安信信托
169
+    - 77、岚儒财富
170
+    - 78、捷道软件
171
+    - 79、湖北享七网络科技有限公司
172
+    - 80、湖南创发科技责任有限公司
173
+    - 81、深圳小安时代互联网金融服务有限公司
174
+    - 82、湖北享七网络科技有限公司
175
+    - 83、钱包行云(北京)科技有限公司
176
+    - 84、360金融 (360)
177
+    - 85、易企秀
178
+    - 86、摩贝(上海)生物科技有限公司
179
+    - 87、广东芯智慧科技有限公司
180
+    - 88、联想集团 (联想)
181
+    - 89、怪兽充电
182
+    - 90、行圆汽车
183
+    - 91、深圳店店通科技邮箱公司
184
+    - 92、京东 (京东)
185
+    - 93、米庄理财
186
+    - 94、咖啡易融
187
+    - 95、梧桐诚选
188
+    - 96、恒大地产 (恒大)
159 189
 	- ……
160 190
 
161 191
 > 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。

+ 59 - 35
doc/XXL-JOB-English-Documentation.md 查看文件

@@ -121,6 +121,35 @@ So far, XXL-JOB has access to a number of companies online product line, access
121 121
     - 65、厦门瓷禧网络有限公司
122 122
     - 66、北京递蓝科软件股份有限公司
123 123
     - 67、郑州创海软件科技公司
124
+    - 68、北京国槐信息科技有限公司
125
+    - 69、浪潮软件集团
126
+    - 70、多立恒(北京)信息技术有限公司
127
+    - 71、广州极迅客信息科技有限公司
128
+    - 72、赫基(中国)集团股份有限公司
129
+    - 73、海投汇
130
+    - 74、上海润益创业孵化器管理股份有限公司
131
+    - 75、汉纳森(厦门)数据股份有限公司
132
+    - 76、安信信托
133
+    - 77、岚儒财富
134
+    - 78、捷道软件
135
+    - 79、湖北享七网络科技有限公司
136
+    - 80、湖南创发科技责任有限公司
137
+    - 81、深圳小安时代互联网金融服务有限公司
138
+    - 82、湖北享七网络科技有限公司
139
+    - 83、钱包行云(北京)科技有限公司
140
+    - 84、360金融 (360)
141
+    - 85、易企秀
142
+    - 86、摩贝(上海)生物科技有限公司
143
+    - 87、广东芯智慧科技有限公司
144
+    - 88、联想集团 (联想)
145
+    - 89、怪兽充电
146
+    - 90、行圆汽车
147
+    - 91、深圳店店通科技邮箱公司
148
+    - 92、京东 (京东)
149
+    - 93、米庄理财
150
+    - 94、咖啡易融
151
+    - 95、梧桐诚选
152
+    - 96、恒大地产 (恒大)
124 153
 	- ……
125 154
 
126 155
 > The company that access and use this product is welcome to register at the [address](https://github.com/xuxueli/xxl-job/issues/1 ), only for product promotion. 
@@ -227,7 +256,7 @@ The concrete contet describe as follows:
227 256
 If you has finished step 1,then you can compile the project in maven and deploy the war package to tomcat.
228 257
 the url to visit is :http://localhost:8080/xxl-job-admin (this address will be used by executor and use it as callback url),the index page after login in is as follow
229 258
 
230
-![index page after login in](https://static.oschina.net/uploads/img/201705/08194505_6yC0.png "index page after login in")
259
+![index page after login in](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_6yC0.png "index page after login in")
231 260
 
232 261
 Now,the “xxl-job-admin” project is deployed success.
233 262
 
@@ -321,16 +350,16 @@ Now let’s create a "GLUE模式(Java)" job,if you want to learn more about it ,
321 350
 #### Step 1:Create new job
322 351
 Login in xxl-job-admin,click on the"新建任务" button, configure the job params as follows and click "保存" button to save the job info.
323 352
 
324
-![task management](https://static.oschina.net/uploads/img/201704/27205910_o8HQ.png "task management")
353
+![task management](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_o8HQ.png "task management")
325 354
 
326
-![create task](https://static.oschina.net/uploads/img/201704/27210202_SE2u.png "create task")
355
+![create task](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAsz.png "create task")
327 356
 
328 357
 #### Step 2:develop “GLUE模式(Java)” job
329 358
 Click “GLUE” button on the right of the job to go to GLUE editor view as shown below。“GLUE模式(Java)” mode task has been inited with default task code for printing Hello World。 ( “GLUE模式(Java)” mode task is a java code fragment implements IJobHandler interface,it will be executed in executor,you can use @Resource/@Autowire to inject other java bean instance,if you want to see more info please go to chapter 3)
330 359
 
331
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210307_Fgql.png "在这里输入图片标题")
360
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Fgql.png "在这里输入图片标题")
332 361
 
333
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210314_dNUJ.png "在这里输入图片标题")
362
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_dNUJ.png "在这里输入图片标题")
334 363
 
335 364
 #### Step 3:trigger task
336 365
 If you want to run the job manually please click "执行" button on the right of the job(usually we trigger job by Cron expression)
@@ -338,11 +367,11 @@ If you want to run the job manually please click "执行" button on the right of
338 367
 #### Step 4:view log 
339 368
 Click “日志” button on the right side of the task you will go to the task log list ,you will see the schedule history records of the task and the schedule detail info,execution info and execution params.If you click the “执行日志” button on the right side of the task log record,you will go to log console and view the execute log in the course of task execution.
340 369
 
341
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232850_inc8.png "在这里输入图片标题")
370
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_inc8.png "在这里输入图片标题")
342 371
 
343 372
 On the log console,you can view task execution log on the executor immediately after it dump to log file,so you can monitor the task execution process by Rolling way.
344 373
 
345
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27211631_eYrv.png "在这里输入图片标题")
374
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_eYrv.png "在这里输入图片标题")
346 375
 
347 376
 ## 3. Task details
348 377
 
@@ -390,12 +419,12 @@ The task logic exist in the executor project as JobHandler,the develop steps as
390 419
     - 3, add  “@JobHandler(value=" customize jobhandler name")” annotation,the value stand for JobHandler name,it will be used as JobHandler property when create a new task in the schedule center.
391 420
     (go and see DemoJobHandler in the xxl-job-executor-example project, as shown below)
392 421
 
393
-![输入图片说明](https://static.oschina.net/uploads/img/201607/23232347_oLlM.png "在这里输入图片标题")
422
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_oLlM.png "在这里输入图片标题")
394 423
 
395 424
 #### Step 2:create task in schedule center
396 425
 If you want learn more about configure item please go and sedd “Description of configuration item”,select  "BEAN模式" as run mode,property JobHandler please fill in the value defined by @JobHande.
397 426
 
398
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27225124_yrcO.png "在这里输入图片标题")
427
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAsz.png "在这里输入图片标题")
399 428
 
400 429
 ### 3.2 GLUE模式(Java)
401 430
 Task source code is maintained in the schedule center and can be updated by Web IDE online, it will be compiled and effective real-time,didn’t need to assign JobHandler,develop flow shown as below:
@@ -403,14 +432,14 @@ Task source code is maintained in the schedule center and can be updated by Web
403 432
 #### Step 1:create task in schedule center
404 433
 If you want learn more about configure item please go and sedd “Description of configuration item”,select "GLUE模式(Java)" as run mode.
405 434
 
406
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210202_SE2u.png "在这里输入图片标题")
435
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_tJOq.png "在这里输入图片标题")
407 436
 
408 437
 #### Step 2:develop task source code
409 438
 Select the task record and click “GLUE” button on the righe of it,it will go to GLUE task’s WEB IDE page,on this page yo can edit you task code(also can edit in other IDE tools,copy and paste into this page).
410 439
 
411 440
 Version backtrack(support 30 versions while backtrack):on the WEB IDE page of GLUE task,on upper right corner drop down box please select “版本回溯”,it will display GLUE updated history,select the version you want it will display the source code of this version,it will backtrace the version while click save button. 
412 441
 
413
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210314_dNUJ.png "在这里输入图片标题")
442
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_dNUJ.png "在这里输入图片标题")
414 443
 
415 444
 ### 3.3 GLUE模式(Shell)
416 445
 
@@ -422,7 +451,7 @@ Select the task record and click “GLUE” button on the righe of it,it will go
422 451
 
423 452
 Actually it is a shell script fragment.
424 453
 
425
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232259_iUw0.png "在这里输入图片标题")
454
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_iUw0.png "在这里输入图片标题")
426 455
 
427 456
 ### 3.4 GLUE模式(Python)
428 457
 
@@ -434,19 +463,19 @@ Select the task record and click “GLUE” button on the righe of it,it will go
434 463
 
435 464
 Actually it is a python script fragment.
436 465
 
437
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232305_BPLG.png "在这里输入图片标题")
466
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_BPLG.png "在这里输入图片标题")
438 467
 
439 468
 
440 469
 ## 4. Task Management
441 470
 ### 4.0 configure executor
442 471
 click"执行器管理" on the left menu,it will go to the page as shown below:
443
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12223509_Hr2T.png "在这里输入图片标题")
472
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Hr2T.png "在这里输入图片标题")
444 473
 
445 474
     1,"调度中心OnLine”:display schedule center machine list,when task is scheduled it will callback schedule center for notify the execution result in failover mode, so that it can avoid a single point scheduler;
446 475
     2,"执行器列表" :display all nodes under this executor group.
447 476
 
448 477
 If you want to create a new executor,please click "+新增执行器" button: 
449
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12223617_g3Im.png "在这里输入图片标题")
478
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_V3vF.png "在这里输入图片标题")
450 479
 
451 480
 ### Description of executor attributes
452 481
 
@@ -473,19 +502,19 @@ choose the task you want to edit and click” GLUE”button on the right side of
473 502
 ### 4.4 pause/recover task
474 503
 You can pause or recover task but it just fit to follow up schedule trigger and won’t affect scheduled tasks,if you want to stop tasks which has been triggered,please go and see “4.8 stop the running task”
475 504
 
476
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24130337_ZAhX.png "在这里输入图片标题")
505
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAhX.png "在这里输入图片标题")
477 506
 
478 507
 ### 4.5 manually trigger
479 508
 You can trigger a task manually by Click “执行”button,it won’t affect original scheduling rules.
480 509
 
481
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24133348_Z5wp.png "在这里输入图片标题")
510
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Z5wp.png "在这里输入图片标题")
482 511
 
483 512
 ### 4.6 view schedule log
484 513
 You can view task’s history schedule log by click “日志” button,on the history schedule log list page you can view every time of task’s schedule result,execution result and so on,click “执行日志” button can view the task’s full execute log.
485 514
 
486
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24133500_9235.png "在这里输入图片标题")
515
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_9235.png "在这里输入图片标题")
487 516
 
488
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232850_inc8.png "在这里输入图片标题")
517
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_inc8.png "在这里输入图片标题")
489 518
 
490 519
     调度时间:schedule center trigger time when schedule and send execution signal to executor;
491 520
     调度结果:schedule center trigger task’s result, 200 represent success,500 or other number stands for fail;
@@ -503,12 +532,12 @@ You can view task’s history schedule log by click “日志” button,on the h
503 532
 ### 4.7 view execution log
504 533
 Click the “执行日志” button on the right side of the record,you can go to the execution log page,you can view the full execution log of the logic business code, shown as below:
505 534
 
506
-![输入图片说明](https://static.oschina.net/uploads/img/201703/25124816_tvGI.png "在这里输入图片标题")
535
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_tvGI.png "在这里输入图片标题")
507 536
 
508 537
 ### 4.8 stop running tasks
509 538
 Just fit to running tasks,on the task log list page,click “终止任务” button on the right side of the record, it will send stop command to the executor where the task was executed,finally the task was killed and the task instance execute queue of this task will be clear.
510 539
 
511
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24140048_hIci.png "在这里输入图片标题")
540
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_hIci.png "在这里输入图片标题")
512 541
 
513 542
 It is implemented by interrupt execute thread, it will trigger InterruptedException.so if JobHandler catch this execuption and handle this exception this function is unavailable.
514 543
 
@@ -529,14 +558,14 @@ If JobHandler start child thread,child thread also must not catch InterruptedExc
529 558
 
530 559
 ### 4.9 delete execution log
531 560
 On the task log list page, after you select executor and task, you can click"删除" button on the right side and it will pop-up "日志清理" window,on the pop-up window you can choose different log delete policy,choose the policy you want to execute and click "确定" button it will delele relative logs:
532
-![输入图片说明](https://static.oschina.net/uploads/img/201705/08210711_Ypik.png "在这里输入图片标题")
561
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Ypik.png "在这里输入图片标题")
533 562
 
534
-![输入图片说明](https://static.oschina.net/uploads/img/201705/08211152_EB65.png "在这里输入图片标题")
563
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_EB65.png "在这里输入图片标题")
535 564
 
536 565
 ### 4.10 delete task
537 566
 Click the delete button on the right side of the task,the task will be deteted.
538 567
 
539
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24140641_Z9Qr.png "在这里输入图片标题")
568
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Z9Qr.png "在这里输入图片标题")
540 569
 
541 570
 ## 5. Overall design
542 571
 ### 5.1 Source directory introduction
@@ -551,7 +580,7 @@ XXL-JOB schedule module is implemented based on Quartz cluster,it’s “databas
551 580
 
552 581
 XXL-JOB custom Quartz table structure prefix(XXL_JOB_QRTZ_).
553 582
 
554
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24143957_bNwm.png "在这里输入图片标题")
583
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_bNwm.png "在这里输入图片标题")
555 584
 
556 585
 The added tables as shown below:
557 586
     - XXL_JOB_QRTZ_TRIGGER_GROUP:executor basic table, maintain the info about the executor;
@@ -580,7 +609,7 @@ So schedule and task can be decoupled from each other, by the way it can improve
580 609
 
581 610
 #### 5.3.3 Architecture diagram
582 611
 
583
-![输入图片说明](https://static.oschina.net/uploads/img/201707/17190028_aEE2.png "在这里输入图片标题")
612
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Qohm.png "在这里输入图片标题")
584 613
 
585 614
 ### 5.4 Schedule module analysis
586 615
 #### 5.4.1 Disadvantage of quartz
@@ -661,10 +690,9 @@ Executor will execute task when it receive task execute request.it will notify t
661 690
 If executor project was deployed as cluster schedule center will known all online executor nodes,such as:“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”.
662 691
 
663 692
 When "路由策略" select "故障转移(FAILOVER)",it will send heart beat check request in order while schedule center start schedule request.  The first alive checked executor node will be selected and send schedule request to it.
664
-![输入图片说明](https://static.oschina.net/uploads/img/201705/11221144_P128.png "在这里输入图片标题")
665 693
 
666 694
 “调度备注” can be viewed on the monitor page when schedule success. As shown below: 
667
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12230733_jrdI.png "在这里输入图片标题")
695
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_jrdI.png "在这里输入图片标题")
668 696
 
669 697
 “调度备注” will display local schedule route path、executor’s "注册方式"、"地址列表" and task’s "路由策略"。Under "故障转移(FAILOVER)" policy, schedule center take first address to do heartbeat detection, heat beat fail will automatically skip, the second address heart beat fail…… until the third address “127.0.0.1:9999” heart beat success, it was selected as target executor, then send schedule request to target executor, now the schedule process is end wait for the executor’s callback execution result.
670 698
 
@@ -675,8 +703,6 @@ Every time when task was scheduled in the schedule center it will record a task
675 703
 - 调度信息:include schedule time、schedule result and  schedule log  and so on,accord these parameters you can understand some task schedule info of schedule center.
676 704
 - 执行信息:include execute time、execute result and execute log and so on, accord these parameters you can understand the task execution info in the executor.
677 705
 
678
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12221436_c8Ru.png "在这里输入图片标题")
679
-
680 706
 Schedule log stands fo single task schedule, attribute description is as follows:
681 707
 - 执行器地址:machine addresses on which task will be executed.
682 708
 - JobHandler:JobHandler name of task under Bean module.
@@ -696,9 +722,9 @@ When parent task end execute and success, it will match child task dependency ac
696 722
 
697 723
 On the task log page ,you can see matched child task and triggered child task’s log info when you “查看”button of “执行备注”,otherwise the child task didin’t execute, as shown beleow:
698 724
 
699
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24194134_Wb2o.png "在这里输入图片标题")
725
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Wb2o.png "在这里输入图片标题")
700 726
 
701
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24194212_jOAU.png "在这里输入图片标题")
727
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_jOAU.png "在这里输入图片标题")
702 728
 
703 729
 ### 5.5 Task "run mode" analysis
704 730
 #### 5.5.1 "Bean模式" task
@@ -722,8 +748,6 @@ All supported types of scripts as shown beloes:
722 748
 #### 5.5.4 executor
723 749
 Executor is actually an embedded Jetty server with default port 9999, as shown below(parameter:xxl.job.executor.port).
724 750
 
725
-![输入图片说明](https://static.oschina.net/uploads/img/201703/10174923_TgNO.png "在这里输入图片标题")
726
-
727 751
 Executor will identify Bean mode task in spring container through @JobHandler When project start, it will be managed use the value of annotation as key. 
728 752
 
729 753
 When executor received schedule request from schedule center, if task type is “Bean模式” it will match bean mode task in Spring container and call it’s execute() method and execute task logic. if task type is “GLUE模式”, it will load Glue code, instantiate a Java object and inject other spring service(notice: the spring service injected in Glue code must exist in the same executor project), then call execute() method and execute task logic. 
@@ -797,7 +821,7 @@ The scheduling center provides API services for executors and business parties t
797 821
 
798 822
 The scheduling center API service location: com.xxl.job.core.biz.AdminBiz.java
799 823
 
800
-The scheduling center API service requests reference code:com.xxl.job.dao.impl.AdminBizTest.java
824
+The scheduling center API service requests reference code:com.xxl.job.adminbiz.AdminBizTest.java
801 825
 
802 826
 
803 827
 ## 6 Version update log

+ 111 - 39
doc/XXL-JOB官方文档.md 查看文件

@@ -134,6 +134,35 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
134 134
     - 65、厦门瓷禧网络有限公司
135 135
     - 66、北京递蓝科软件股份有限公司
136 136
     - 67、郑州创海软件科技公司
137
+    - 68、北京国槐信息科技有限公司
138
+    - 69、浪潮软件集团
139
+    - 70、多立恒(北京)信息技术有限公司
140
+    - 71、广州极迅客信息科技有限公司
141
+    - 72、赫基(中国)集团股份有限公司
142
+    - 73、海投汇
143
+    - 74、上海润益创业孵化器管理股份有限公司
144
+    - 75、汉纳森(厦门)数据股份有限公司
145
+    - 76、安信信托
146
+    - 77、岚儒财富
147
+    - 78、捷道软件
148
+    - 79、湖北享七网络科技有限公司
149
+    - 80、湖南创发科技责任有限公司
150
+    - 81、深圳小安时代互联网金融服务有限公司
151
+    - 82、湖北享七网络科技有限公司
152
+    - 83、钱包行云(北京)科技有限公司
153
+    - 84、360金融 (360)
154
+    - 85、易企秀
155
+    - 86、摩贝(上海)生物科技有限公司
156
+    - 87、广东芯智慧科技有限公司
157
+    - 88、联想集团 (联想)
158
+    - 89、怪兽充电
159
+    - 90、行圆汽车
160
+    - 91、深圳店店通科技邮箱公司
161
+    - 92、京东 (京东)
162
+    - 93、米庄理财
163
+    - 94、咖啡易融
164
+    - 95、梧桐诚选
165
+    - 96、恒大地产 (恒大)
137 166
 	- ……
138 167
 
139 168
 > 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。
@@ -227,6 +256,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
227 256
     ### 报警邮箱
228 257
     xxl.job.mail.host=smtp.163.com
229 258
     xxl.job.mail.port=25
259
+    xxl.job.mail.ssl=false
230 260
     xxl.job.mail.username=ovono802302@163.com
231 261
     xxl.job.mail.password=asdfzxcv
232 262
     xxl.job.mail.sendFrom=ovono802302@163.com
@@ -246,7 +276,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
246 276
 如果已经正确进行上述配置,可将项目编译打war包并部署到tomcat中。
247 277
 调度中心访问地址:http://localhost:8080/xxl-job-admin (该地址执行器将会使用到,作为回调地址),登录后运行界面如下图所示
248 278
 
249
-![输入图片说明](https://static.oschina.net/uploads/img/201705/08194505_6yC0.png "在这里输入图片标题")
279
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_6yC0.png "在这里输入图片标题")
250 280
 
251 281
 至此“调度中心”项目已经部署成功。
252 282
 
@@ -351,18 +381,18 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
351 381
 #### 步骤一:新建任务:
352 382
 登录调度中心,点击下图所示“新建任务”按钮,新建示例任务。然后,参考下面截图中任务的参数配置,点击保存。
353 383
 
354
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27205910_o8HQ.png "在这里输入图片标题")
384
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_o8HQ.png "在这里输入图片标题")
355 385
 
356
-![输入图片说明](https://static.oschina.net/uploads/img/201712/25183654_ZAsz.png "在这里输入图片标题")
386
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAsz.png "在这里输入图片标题")
357 387
 
358 388
 
359 389
 #### 步骤二:“GLUE模式(Java)” 任务开发:
360 390
 请点击任务右侧 “GLUE” 按钮,进入 “GLUE编辑器开发界面” ,见下图。“GLUE模式(Java)” 运行模式的任务默认已经初始化了示例任务代码,即打印Hello World。
361 391
 ( “GLUE模式(Java)” 运行模式的任务实际上是一段继承自IJobHandler的Java类代码,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务,详细介绍请查看第三章节)
362 392
 
363
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210307_Fgql.png "在这里输入图片标题")
393
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Fgql.png "在这里输入图片标题")
364 394
 
365
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210314_dNUJ.png "在这里输入图片标题")
395
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_dNUJ.png "在这里输入图片标题")
366 396
 
367 397
 #### 步骤三:触发执行:
368 398
 请点击任务右侧 “执行” 按钮,可手动触发一次任务执行(通常情况下,通过配置Cron表达式进行任务调度出发)。
@@ -371,11 +401,11 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
371 401
 请点击任务右侧 “日志” 按钮,可前往任务日志界面查看任务日志。
372 402
 在任务日志界面中,可查看该任务的历史调度记录以及每一次调度的任务调度信息、执行参数和执行信息。运行中的任务点击右侧的“执行日志”按钮,可进入日志控制台查看实时执行日志。
373 403
 
374
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232850_inc8.png "在这里输入图片标题")
404
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_inc8.png "在这里输入图片标题")
375 405
 
376 406
 在日志控制台,可以Rolling方式实时查看任务在执行器一侧运行输出的日志信息,实时监控任务进度;
377 407
 
378
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27211631_eYrv.png "在这里输入图片标题")
408
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_eYrv.png "在这里输入图片标题")
379 409
 
380 410
 ## 三、任务详解
381 411
 
@@ -426,12 +456,12 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
426 456
      - 4、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
427 457
     (可参考Sample示例执行器中的DemoJobHandler,见下图)
428 458
 
429
-![输入图片说明](https://static.oschina.net/uploads/img/201607/23232347_oLlM.png "在这里输入图片标题")
459
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_oLlM.png "在这里输入图片标题")
430 460
 
431 461
 #### 步骤二:调度中心,新建调度任务
432 462
 参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "BEAN模式",JobHandler属性填写任务注解“@JobHandler”中定义的值;
433 463
 
434
-![输入图片说明](https://static.oschina.net/uploads/img/201712/25183654_ZAsz.png "在这里输入图片标题")
464
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAsz.png "在这里输入图片标题")
435 465
 
436 466
 ### 3.2 GLUE模式(Java)
437 467
 任务以源码方式维护在调度中心,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。开发流程如下:
@@ -439,14 +469,14 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
439 469
 #### 步骤一:调度中心,新建调度任务:
440 470
 参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "GLUE模式(Java)";
441 471
 
442
-![输入图片说明](https://static.oschina.net/uploads/img/201712/25183837_tJOq.png "在这里输入图片标题")
472
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_tJOq.png "在这里输入图片标题")
443 473
 
444 474
 #### 步骤二:开发任务代码:
445 475
 选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。
446 476
 
447 477
 版本回溯功能(支持30个版本的版本回溯):在GLUE任务的Web IDE界面,选择右上角下拉框“版本回溯”,会列出该GLUE的更新历史,选择相应版本即可显示该版本代码,保存后GLUE代码即回退到对应的历史版本;
448 478
 
449
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27210314_dNUJ.png "在这里输入图片标题")
479
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_dNUJ.png "在这里输入图片标题")
450 480
 
451 481
 ### 3.3 GLUE模式(Shell)
452 482
 
@@ -458,7 +488,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
458 488
 
459 489
 该模式的任务实际上是一段 "shell" 脚本;
460 490
 
461
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232259_iUw0.png "在这里输入图片标题")
491
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_iUw0.png "在这里输入图片标题")
462 492
 
463 493
 ### 3.4 GLUE模式(Python)
464 494
 
@@ -470,7 +500,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
470 500
 
471 501
 该模式的任务实际上是一段 "python" 脚本;
472 502
 
473
-![输入图片说明](https://static.oschina.net/uploads/img/201704/27232305_BPLG.png "在这里输入图片标题")
503
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_BPLG.png "在这里输入图片标题")
474 504
 
475 505
 ### 3.5 GLUE模式(NodeJS)
476 506
 
@@ -487,14 +517,14 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
487 517
 
488 518
 ### 4.0 配置执行器  
489 519
 点击进入"执行器管理"界面, 如下图:
490
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12223509_Hr2T.png "在这里输入图片标题")
520
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Hr2T.png "在这里输入图片标题")
491 521
 
492 522
     1、"调度中心OnLine:"右侧显示在线的"调度中心"列表, 任务执行结束后, 将会以failover的模式进行回调调度中心通知执行结果, 避免回调的单点风险;
493 523
     2、"执行器列表" 中显示在线的执行器列表, 可通过"OnLine 机器"查看对应执行器的集群机器。
494 524
 
495 525
 点击按钮 "+新增执行器" 弹框如下图, 可新增执行器配置:
496 526
 
497
-![输入图片说明](https://static.oschina.net/uploads/img/201712/25183958_V3vF.png "在这里输入图片标题")
527
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_V3vF.png "在这里输入图片标题")
498 528
 
499 529
 ### 执行器属性说明
500 530
 
@@ -522,19 +552,19 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
522 552
 可对任务进行“暂停”和“恢复”操作。
523 553
 需要注意的是,此处的暂停/恢复仅针对任务的后续调度触发行为,不会影响到已经触发的调度任务,如需终止已经触发的调度任务,可查看“4.8 终止运行中的任务”
524 554
 
525
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24130337_ZAhX.png "在这里输入图片标题")
555
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_ZAhX.png "在这里输入图片标题")
526 556
 
527 557
 ### 4.5 手动触发一次调度
528 558
 点击“执行”按钮,可手动触发一次任务调度,不影响原有调度规则。
529 559
 
530
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24133348_Z5wp.png "在这里输入图片标题")
560
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Z5wp.png "在这里输入图片标题")
531 561
 
532 562
 ### 4.6 查看调度日志
533 563
 点击“日志”按钮,可以查看任务历史调度日志。在历史调入日志界面可查看每次任务调度的调度结果、执行结果等,点击“执行日志”按钮可查看执行器完整日志。
534 564
 
535
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24133500_9235.png "在这里输入图片标题")
565
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_9235.png "在这里输入图片标题")
536 566
 
537
-![输入图片说明](https://static.oschina.net/uploads/img/201712/25184206_UDSo.png "在这里输入图片标题")
567
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_UDSo.png "在这里输入图片标题")
538 568
 
539 569
     调度时间:"调度中心"触发本次调度并向"执行器"发送任务执行信号的时间;
540 570
     调度结果:"调度中心"触发本次调度的结果,200表示成功,500或其他表示失败;
@@ -552,13 +582,13 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
552 582
 ### 4.7 查看执行日志
553 583
 点击执行日志右侧的 “执行日志” 按钮,可跳转至执行日志界面,可以查看业务代码中打印的完整日志,如下图;
554 584
 
555
-![输入图片说明](https://static.oschina.net/uploads/img/201703/25124816_tvGI.png "在这里输入图片标题")
585
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_tvGI.png "在这里输入图片标题")
556 586
 
557 587
 ### 4.8 终止运行中的任务
558 588
 仅针对执行中的任务。
559 589
 在任务日志界面,点击右侧的“终止任务”按钮,将会向本次任务对应的执行器发送任务终止请求,将会终止掉本次任务,同时会清空掉整个任务执行队列。
560 590
 
561
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24140048_hIci.png "在这里输入图片标题")
591
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_hIci.png "在这里输入图片标题")
562 592
 
563 593
 任务终止时通过 "interrupt" 执行线程的方式实现, 将会触发 "InterruptedException" 异常。因此如果JobHandler内部catch到了该异常并消化掉的话, 任务终止功能将不可用。
564 594
 
@@ -579,14 +609,14 @@ try{
579 609
 
580 610
 ### 4.9 删除执行日志
581 611
 在任务日志界面,选中执行器和任务之后,点击右侧的"删除"按钮将会出现"日志清理"弹框,弹框中支持选择不同类型的日志清理策略,选中后点击"确定"按钮即可进行日志清理操作;
582
-![输入图片说明](https://static.oschina.net/uploads/img/201705/08210711_Ypik.png "在这里输入图片标题")
612
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Ypik.png "在这里输入图片标题")
583 613
 
584
-![输入图片说明](https://static.oschina.net/uploads/img/201705/08211152_EB65.png "在这里输入图片标题")
614
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_EB65.png "在这里输入图片标题")
585 615
 
586 616
 ### 4.10 删除任务
587 617
 点击删除按钮,可以删除对应任务。
588 618
 
589
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24140641_Z9Qr.png "在这里输入图片标题")
619
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Z9Qr.png "在这里输入图片标题")
590 620
 
591 621
 
592 622
 ## 五、总体设计
@@ -602,7 +632,7 @@ XXL-JOB调度模块基于Quartz集群实现,其“调度数据库”是在Quar
602 632
 
603 633
 XXL-JOB首先定制了Quartz原生表结构前缀(XXL_JOB_QRTZ_)。
604 634
 
605
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24143957_bNwm.png "在这里输入图片标题")
635
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_bNwm.png "在这里输入图片标题")
606 636
 
607 637
 然后,在此基础上新增了几张张扩展表,如下:
608 638
     - XXL_JOB_QRTZ_TRIGGER_GROUP:执行器信息表,维护任务执行器信息;
@@ -631,14 +661,17 @@ XXL-JOB首先定制了Quartz原生表结构前缀(XXL_JOB_QRTZ_)。
631 661
 
632 662
 #### 5.3.3 架构图
633 663
 
634
-![输入图片说明](https://static.oschina.net/uploads/img/201801/03103007_Qohm.png "在这里输入图片标题")
664
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Qohm.png "在这里输入图片标题")
635 665
 
636 666
 ### 5.4 调度模块剖析
637 667
 #### 5.4.1 quartz的不足
638 668
 Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题:
639
-    - 问题一:调用API的的方式操作任务,不人性化;
640
-    - 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
641
-    - 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;
669
+   
670
+- 问题一:调用API的的方式操作任务,不人性化;
671
+- 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
672
+- 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;
673
+- 问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。
674
+
642 675
 XXL-JOB弥补了quartz的上述不足之处。
643 676
 
644 677
 #### 5.4.2 RemoteHttpJobBean
@@ -727,7 +760,7 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
727 760
 当任务"路由策略"选择"故障转移(FAILOVER)"时,当调度中心每次发起调度请求时,会按照顺序对执行器发出心跳检测请求,第一个检测为存活状态的执行器将会被选定并发送调度请求。
728 761
 
729 762
 调度成功后,可在日志监控界面查看“调度备注”,如下;
730
-![输入图片说明](https://static.oschina.net/uploads/img/201703/12230733_jrdI.png "在这里输入图片标题")
763
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_jrdI.png "在这里输入图片标题")
731 764
 
732 765
 “调度备注”可以看出本地调度运行轨迹,执行器的"注册方式"、"地址列表"和任务的"路由策略"。"故障转移(FAILOVER)"路由策略下,调度中心首先对第一个地址进行心跳检测,心跳失败因此自动跳过,第二个依然心跳检测失败……
733 766
 直至心跳检测第三个地址“127.0.0.1:9999”成功,选定为“目标执行器”;然后对“目标执行器”发送调度请求,调度流程结束,等待执行器回调执行结果。
@@ -758,9 +791,9 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
758 791
 
759 792
 在任务日志界面,点击任务的“执行备注”的“查看”按钮,可以看到匹配子任务以及触发子任务执行的日志信息,如无信息则表示未触发子任务执行,可参考下图。
760 793
 
761
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24194134_Wb2o.png "在这里输入图片标题")
794
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_Wb2o.png "在这里输入图片标题")
762 795
 
763
-![输入图片说明](https://static.oschina.net/uploads/img/201607/24194212_jOAU.png "在这里输入图片标题")
796
+![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-job/master/doc/images/img_jOAU.png "在这里输入图片标题")
764 797
 
765 798
 ### 5.5 任务 "运行模式" 剖析
766 799
 #### 5.5.1 "Bean模式" 任务
@@ -773,14 +806,15 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
773 806
 
774 807
 #### 5.5.3 GLUE模式(Shell) + GLUE模式(Python) + GLUE模式(NodeJS)
775 808
 开发步骤:可参考 "章节三" ;
776
-原理:脚本任务的源码托管在调度中心,脚本逻辑在执行器运行。当触发脚本任务时,执行器会加载脚本源码在执行器机器上生成一份脚本文件,然后通过Java代码调用该脚本;并且实时将脚本输出日志写到任务日志文件中,从而在调度中心可以实时监控脚本运行情况;脚本返回码为0时表示执行成功,其他标示执行失败。
809
+原理:脚本任务的源码托管在调度中心,脚本逻辑在执行器运行。当触发脚本任务时,执行器会加载脚本源码在执行器机器上生成一份脚本文件,然后通过Java代码调用该脚本;并且实时将脚本输出日志写到任务日志文件中,从而在调度中心可以实时监控脚本运行情况;
777 810
 
778 811
 目前支持的脚本类型如下:
779 812
 
780 813
     - shell脚本:任务运行模式选择为 "GLUE模式(Shell)"时支持 "shell" 脚本任务;
781 814
     - python脚本:任务运行模式选择为 "GLUE模式(Python)"时支持 "python" 脚本任务;
782 815
     - nodejs脚本:务运行模式选择为 "GLUE模式(NodeJS)"时支持 "nodejs" 脚本任务;
783
-    
816
+
817
+脚本任务通过 Exit Code 判断任务执行结果,状态码可参考章节 "5.15 任务执行结果说明";
784 818
 
785 819
 #### 5.5.4 执行器
786 820
 执行器实际上是一个内嵌的Jetty服务器,默认端口9999(配置项:xxl.job.executor.port)。
@@ -895,6 +929,25 @@ echo "分片总数 total = $3"
895 929
     - 调度中心调度失败时,任务失败处理策略选择"失败重试",将会自动重试一次;
896 930
     - 执行器运行失败时,任务执行结果返回"失败重试(IJobHandler.FAIL_RETRY)"回调,将会自动重试一次;
897 931
 
932
+### 5.14 执行器灰度上线
933
+调度中心与业务解耦,只需部署一次后常年不需要维护。但是,执行器中托管运行着业务作业,作业上线和变更需要重启执行器,尤其是Bean模式任务。
934
+执行器重启可能会中断运行中的任务。但是,XXL-JOB得益于自建执行器与自建注册中心,可以通过灰度上线的方式,避免因重启导致的任务中断的问题。
935
+
936
+步骤如下:
937
+- 1、执行器改为手动注册,下线一半机器列表(A组),线上运行另一半机器列表(B组);
938
+- 2、等待A组机器任务运行结束并编译上线;执行器注册地址替换为A组;
939
+- 3、等待B组机器任务运行结束并编译上线;执行器注册地址替换为A组+B组;
940
+操作结束;
941
+
942
+### 5.15 任务执行结果说明
943
+系统根据以下标准判断任务执行结果,可参考之。
944
+
945
+-- | Bean/Glue(Java) | Glue(Shell) 等脚本任务
946
+--- | --- | ---
947
+成功 | IJobHandler.SUCCESS | 0
948
+失败 | IJobHandler.FAIL | -1(其他)
949
+失败重试 | IJobHandler.FAIL_RETRY | 101
950
+
898 951
 
899 952
 ## 六、版本更新日志
900 953
 ### 6.1 版本 V1.1.x,新特性[2015-12-05]
@@ -1154,6 +1207,22 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1154 1207
 - 8、项目依赖全量升级至较新稳定版本,如spring、jackson等等;
1155 1208
 
1156 1209
 ### 6.22 版本 V1.9.2 特性[迭代中]
1210
+- 1、[迭代中]支持通过API服务操作任务信息;
1211
+- 2、[迭代中]任务告警逻辑调整:任务调度,以及任务回调失败时,均推送监控队列。后期考虑通过任务Log字段控制告警状态;
1212
+- 3、[迭代中]任务超时设置,超时任务主动终止;
1213
+- 4、任务属性枚举 "任务模式、阻塞策略" 国际化优化;
1214
+- 5、任务日志表状态字段类型优化;
1215
+- 6、Glue(Shell) 等脚本任务支持失败重试;
1216
+- 7、告警邮箱支持SSL配置;
1217
+- 8、Window机器下File.separator不兼容问题修复;
1218
+- 9、任务日志查询速度优化,百万级别日志量搜索速度提升1000倍;
1219
+- 10、底层LocalCache组件兼容性优化,支持jdk、jdk10编译部署;
1220
+- 11、任务回调结果优化,支持展示在Rolling log中,方便问题排查;
1221
+- 12、脚本任务异常Log输出优化;
1222
+- 13、任务线程停止变量修饰符优化;
1223
+- 14、脚本任务Log文件流关闭优化;
1224
+- 15、任务报表成功、失败和进行中统计问题修复;
1225
+- 16、自研Log组件参数占位符改为"{}",并修复打印有参日志时参数不匹配导致报错的问题;
1157 1226
 
1158 1227
 
1159 1228
 ### TODO LIST
@@ -1165,7 +1234,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1165 1234
 - 6、调度任务优先级;
1166 1235
 - 7、移除quartz依赖,重写调度模块:新增或恢复任务时将下次执行记录插入delayqueue,调度中心集群竞争分布式锁,成功节点批量加载到期delayqueue数据,批量执行。
1167 1236
 - 8、springboot 和 docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
1168
-- 9、任务告警逻辑调整:任务调度,以及任务回调失败时,均推送监控队列。后期考虑通过任务Log字段控制告警状态
1237
+- 9、多数据库支持
1169 1238
 - 10、执行器Log清理功能:调度中心Log删除时同步删除执行器中的Log文件;
1170 1239
 - 11、Bean模式任务,JobHandler自动从执行器中查询展示为下拉框,选择后自动填充任务名称等属性;
1171 1240
 - 12、API事件触发类型任务(更类似MQ消息)支持"动态传参、延时消费";该类型任务不走Quartz,单独建立MQ消息表,调度中心竞争触发;
@@ -1175,10 +1244,13 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1175 1244
 - 16、新增API服务 "XxlJobService" ,支持通过API服务来维护管理任务信息;
1176 1245
 - 17、新增任务默认运行状态,任务更新时运行状态保持不变;
1177 1246
 - 18、告警邮件中展示失败告警信息;
1178
-- 19、多数据库支持;
1179
-- 20、提供多版本执行器:不依赖容器版本、不内嵌Jetty版本等;
1180
-- 21、支持通过API服务操作任务信息;
1181
-- 22、任务超时设置,超时任务主动终止;
1247
+- 19、提供多版本执行器:不依赖容器版本、不内嵌Jetty版本(通过配置executoraddress替换jetty通讯)等;
1248
+- 20、注册中心支持扩展,除默认基于DB之外,支持扩展接入第三方注册中心如zk、eureka等;
1249
+- 21、依赖Core内部国际化处理;
1250
+- 22、故障转移、失败重试等策略,规范化合并归类;
1251
+- 23、流程任务,支持参数传递;
1252
+- 24、SimpleTrigger 支持;
1253
+- 25、springboot热部署支持;
1182 1254
 
1183 1255
 
1184 1256
 ## 七、其他

+ 4 - 3
doc/db/tables_xxl_job.sql 查看文件

@@ -181,12 +181,13 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_LOG` (
181 181
   `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
182 182
   `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
183 183
   `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
184
-  `trigger_code` varchar(255) NOT NULL DEFAULT '0' COMMENT '调度-结果',
184
+  `trigger_code` int(11) NOT NULL COMMENT '调度-结果',
185 185
   `trigger_msg` varchar(2048) DEFAULT NULL COMMENT '调度-日志',
186 186
   `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
187
-  `handle_code` varchar(255) NOT NULL DEFAULT '0' COMMENT '执行-状态',
187
+  `handle_code` int(11) NOT NULL COMMENT '执行-状态',
188 188
   `handle_msg` varchar(2048) DEFAULT NULL COMMENT '执行-日志',
189
-  PRIMARY KEY (`id`)
189
+  PRIMARY KEY (`id`),
190
+  KEY `I_trigger_time` (`trigger_time`)
190 191
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
191 192
 
192 193
 CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_LOGGLUE` (

二進制
doc/images/img_6yC0.png 查看文件


二進制
doc/images/img_9235.png 查看文件


二進制
doc/images/img_BPLG.png 查看文件


二進制
doc/images/img_EB65.png 查看文件


二進制
doc/images/img_Fgql.png 查看文件


二進制
doc/images/img_Hr2T.png 查看文件


二進制
doc/images/img_Qohm.png 查看文件


二進制
doc/images/img_UDSo.png 查看文件


二進制
doc/images/img_V3vF.png 查看文件


二進制
doc/images/img_Wb2o.png 查看文件


二進制
doc/images/img_Ypik.png 查看文件


二進制
doc/images/img_Z5wp.png 查看文件


二進制
doc/images/img_Z9Qr.png 查看文件


二進制
doc/images/img_ZAhX.png 查看文件


二進制
doc/images/img_ZAsz.png 查看文件


二進制
doc/images/img_bNwm.png 查看文件


二進制
doc/images/img_dNUJ.png 查看文件


二進制
doc/images/img_eYrv.png 查看文件


二進制
doc/images/img_hIci.png 查看文件


二進制
doc/images/img_iUw0.png 查看文件


二進制
doc/images/img_inc8.png 查看文件


二進制
doc/images/img_jOAU.png 查看文件


二進制
doc/images/img_jrdI.png 查看文件


二進制
doc/images/img_o8HQ.png 查看文件


二進制
doc/images/img_oLlM.png 查看文件


二進制
doc/images/img_tJOq.png 查看文件


二進制
doc/images/img_tvGI.png 查看文件


+ 7 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java 查看文件

@@ -27,6 +27,9 @@ public class XxlJobAdminConfig implements InitializingBean{
27 27
     @Value("${xxl.job.mail.port}")
28 28
     private String mailPort;
29 29
 
30
+    @Value("${xxl.job.mail.ssl}")
31
+    private boolean mailSSL;
32
+
30 33
     @Value("${xxl.job.mail.username}")
31 34
     private String mailUsername;
32 35
 
@@ -54,6 +57,10 @@ public class XxlJobAdminConfig implements InitializingBean{
54 57
         return mailPort;
55 58
     }
56 59
 
60
+    public boolean isMailSSL() {
61
+        return mailSSL;
62
+    }
63
+
57 64
     public String getMailUsername() {
58 65
         return mailUsername;
59 66
     }

+ 11 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/core/schedule/XxlJobDynamicScheduler.java 查看文件

@@ -4,12 +4,14 @@ import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
4 4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5 5
 import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
6 6
 import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper;
7
+import com.xxl.job.admin.core.util.I18nUtil;
7 8
 import com.xxl.job.admin.dao.XxlJobGroupDao;
8 9
 import com.xxl.job.admin.dao.XxlJobInfoDao;
9 10
 import com.xxl.job.admin.dao.XxlJobLogDao;
10 11
 import com.xxl.job.admin.dao.XxlJobRegistryDao;
11 12
 import com.xxl.job.core.biz.AdminBiz;
12 13
 import com.xxl.job.core.biz.ExecutorBiz;
14
+import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
13 15
 import com.xxl.job.core.rpc.netcom.NetComClientProxy;
14 16
 import com.xxl.job.core.rpc.netcom.NetComServerFactory;
15 17
 import org.quartz.*;
@@ -76,11 +78,20 @@ public final class XxlJobDynamicScheduler implements ApplicationContextAware {
76 78
         NetComServerFactory.putService(AdminBiz.class, XxlJobDynamicScheduler.adminBiz);
77 79
         NetComServerFactory.setAccessToken(accessToken);
78 80
 
81
+        // init i18n
82
+        initI18n();
83
+
79 84
         // valid
80 85
         Assert.notNull(scheduler, "quartz scheduler is null");
81 86
         logger.info(">>>>>>>>> init xxl-job admin success.");
82 87
     }
83 88
 
89
+    private void initI18n(){
90
+        for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
91
+            item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
92
+        }
93
+    }
94
+
84 95
     public void destroy(){
85 96
         // admin registry stop
86 97
         JobRegistryMonitorHelper.getInstance().toStop();

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java 查看文件

@@ -56,22 +56,22 @@ public class JobFailMonitorHelper {
56 56
 									continue;
57 57
 								}
58 58
 								if (IJobHandler.SUCCESS.getCode() == log.getTriggerCode() && log.getHandleCode() == 0) {
59
+									// job running
59 60
 									JobFailMonitorHelper.monitor(jobLogId);
60 61
 									logger.info(">>>>>>>>>>> job monitor, job running, JobLogId:{}", jobLogId);
61 62
 								} else if (IJobHandler.SUCCESS.getCode() == log.getHandleCode()) {
62 63
 									// job success, pass
63 64
 									logger.info(">>>>>>>>>>> job monitor, job success, JobLogId:{}", jobLogId);
64
-								} else if (IJobHandler.FAIL.getCode() == log.getTriggerCode()
65
+								} else /*if (IJobHandler.FAIL.getCode() == log.getTriggerCode()
65 66
 										|| IJobHandler.FAIL.getCode() == log.getHandleCode()
66
-										|| IJobHandler.TIMEOUT.getCode() == log.getHandleCode()
67
-										|| IJobHandler.FAIL_RETRY.getCode() == log.getHandleCode() ) {
67
+										|| IJobHandler.FAIL_RETRY.getCode() == log.getHandleCode() )*/ {
68 68
 									// job fail,
69 69
 									failAlarm(log);
70 70
 									logger.info(">>>>>>>>>>> job monitor, job fail, JobLogId:{}", jobLogId);
71
-								} else {
71
+								}/* else {
72 72
 									JobFailMonitorHelper.monitor(jobLogId);
73 73
 									logger.info(">>>>>>>>>>> job monitor, job status unknown, JobLogId:{}", jobLogId);
74
-								}
74
+								}*/
75 75
 							}
76 76
 						}
77 77
 

+ 1 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/I18nUtil.java 查看文件

@@ -30,7 +30,7 @@ public class I18nUtil {
30 30
             return prop;
31 31
         }
32 32
         try {
33
-            // bild i18n prop
33
+            // build i18n prop
34 34
             String i18n = XxlJobAdminConfig.getAdminConfig().getI18n();
35 35
             i18n = StringUtils.isNotBlank(i18n)?("_"+i18n):i18n;
36 36
             String i18nFile = MessageFormat.format("i18n/message{0}.properties", i18n);

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/LocalCacheUtil.java 查看文件

@@ -3,6 +3,7 @@ package com.xxl.job.admin.core.util;
3 3
 import org.apache.commons.lang3.StringUtils;
4 4
 
5 5
 import java.util.concurrent.ConcurrentHashMap;
6
+import java.util.concurrent.ConcurrentMap;
6 7
 
7 8
 /**
8 9
  * local cache tool
@@ -11,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
11 12
  */
12 13
 public class LocalCacheUtil {
13 14
 
14
-    private static ConcurrentHashMap<String, LocalCacheData> cacheRepository = new ConcurrentHashMap<>();
15
+    private static ConcurrentMap<String, LocalCacheData> cacheRepository = new ConcurrentHashMap<String, LocalCacheData>();   // 类型建议用抽象父类,兼容性更好;
15 16
     private static class LocalCacheData{
16 17
         private String key;
17 18
         private Object val;

+ 8 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/MailUtil.java 查看文件

@@ -35,8 +35,14 @@ public class MailUtil {
35 35
 			//email.setSSL(true);
36 36
 
37 37
 			email.setHostName(XxlJobAdminConfig.getAdminConfig().getMailHost());
38
-			email.setSmtpPort(Integer.valueOf(XxlJobAdminConfig.getAdminConfig().getMailPort()));
39
-			//email.setSslSmtpPort(port);
38
+
39
+			if (XxlJobAdminConfig.getAdminConfig().isMailSSL()) {
40
+				email.setSslSmtpPort(XxlJobAdminConfig.getAdminConfig().getMailPort());
41
+				email.setSSLOnConnect(true);
42
+			} else {
43
+				email.setSmtpPort(Integer.valueOf(XxlJobAdminConfig.getAdminConfig().getMailPort()));
44
+			}
45
+
40 46
 			email.setAuthenticator(new DefaultAuthenticator(XxlJobAdminConfig.getAdminConfig().getMailUsername(), XxlJobAdminConfig.getAdminConfig().getMailPassword()));
41 47
 			email.setCharset(Charset.defaultCharset().name());
42 48
 

+ 4 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java 查看文件

@@ -6,7 +6,6 @@ import com.xxl.job.admin.core.model.XxlJobInfo;
6 6
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
7 7
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
8 8
 import com.xxl.job.admin.core.util.I18nUtil;
9
-import com.xxl.job.admin.core.util.LocalCacheUtil;
10 9
 import com.xxl.job.admin.dao.XxlJobGroupDao;
11 10
 import com.xxl.job.admin.dao.XxlJobInfoDao;
12 11
 import com.xxl.job.admin.dao.XxlJobLogDao;
@@ -324,12 +323,12 @@ public class XxlJobServiceImpl implements XxlJobService {
324 323
 	private static final String TRIGGER_CHART_DATA_CACHE = "trigger_chart_data_cache";
325 324
 	@Override
326 325
 	public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate) {
327
-		// get cache
326
+		/*// get cache
328 327
 		String cacheKey = TRIGGER_CHART_DATA_CACHE + "_" + startDate.getTime() + "_" + endDate.getTime();
329 328
 		Map<String, Object> chartInfo = (Map<String, Object>) LocalCacheUtil.get(cacheKey);
330 329
 		if (chartInfo != null) {
331 330
 			return new ReturnT<Map<String, Object>>(chartInfo);
332
-		}
331
+		}*/
333 332
 
334 333
 		// process
335 334
 		List<String> triggerDayList = new ArrayList<String>();
@@ -376,8 +375,8 @@ public class XxlJobServiceImpl implements XxlJobService {
376 375
 		result.put("triggerCountSucTotal", triggerCountSucTotal);
377 376
 		result.put("triggerCountFailTotal", triggerCountFailTotal);
378 377
 
379
-		// set cache
380
-		LocalCacheUtil.set(cacheKey, result, 60*1000);     // cache 60s
378
+		/*// set cache
379
+		LocalCacheUtil.set(cacheKey, result, 60*1000);     // cache 60s*/
381 380
 
382 381
 		return new ReturnT<Map<String, Object>>(result);
383 382
 	}

+ 3 - 0
xxl-job-admin/src/main/resources/i18n/message.properties 查看文件

@@ -193,6 +193,9 @@ jobgroup_del_limit_0=拒绝删除,该执行器使用中
193 193
 jobgroup_del_limit_1=拒绝删除, 系统至少保留一个执行器
194 194
 
195 195
 ## job conf
196
+jobconf_block_SERIAL_EXECUTION=单机串行
197
+jobconf_block_DISCARD_LATER=丢弃后续调度
198
+jobconf_block_COVER_EARLY=覆盖之前调度
196 199
 jobconf_fail_alarm=失败告警
197 200
 jobconf_fail_retry=失败重试
198 201
 jobconf_route_first=第一个

+ 3 - 0
xxl-job-admin/src/main/resources/i18n/message_en.properties 查看文件

@@ -193,6 +193,9 @@ jobgroup_del_limit_0=Refuse to delete, the executor is being used
193 193
 jobgroup_del_limit_1=Refuses to delete, the system retains at least one executor
194 194
 
195 195
 ## job conf
196
+jobconf_block_SERIAL_EXECUTION=Serial execution
197
+jobconf_block_DISCARD_LATER=Discard Later
198
+jobconf_block_COVER_EARLY=Cover Early
196 199
 jobconf_fail_alarm=Fail Alarm
197 200
 jobconf_fail_retry=Fail Retry
198 201
 jobconf_route_first=First

+ 17 - 11
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml 查看文件

@@ -45,7 +45,7 @@
45 45
 		SELECT <include refid="Base_Column_List" />
46 46
 		FROM XXL_JOB_QRTZ_TRIGGER_LOG AS t
47 47
 		<trim prefix="WHERE" prefixOverrides="AND | OR" >
48
-			<if test="jobGroup != null and jobGroup != ''">
48
+			<if test="jobGroup gt 0">
49 49
 				AND t.job_group = #{jobGroup}
50 50
 			</if>
51 51
 			<if test="jobId gt 0">
@@ -62,12 +62,13 @@
62 62
 			</if>
63 63
 			<if test="logStatus == 2" >
64 64
 				AND (
65
-					(t.trigger_code <![CDATA[ > ]]> 0 AND t.trigger_code!=200) ||
66
-					(t.handle_code <![CDATA[ > ]]> 0 AND t.handle_code!=200)
65
+					t.trigger_code NOT IN (0, 200) OR
66
+					t.handle_code NOT IN (0, 200)
67 67
 				)
68 68
 			</if>
69 69
 			<if test="logStatus == 3" >
70
-				AND (t.trigger_code = 200 AND t.handle_code=0)
70
+				AND t.trigger_code = 200
71
+				AND t.handle_code = 0
71 72
 			</if>
72 73
 		</trim>
73 74
 		ORDER BY id DESC
@@ -78,7 +79,7 @@
78 79
 		SELECT count(1)
79 80
 		FROM XXL_JOB_QRTZ_TRIGGER_LOG AS t
80 81
 		<trim prefix="WHERE" prefixOverrides="AND | OR" >
81
-			<if test="jobGroup != null and jobGroup != ''">
82
+			<if test="jobGroup gt 0">
82 83
 				AND t.job_group = #{jobGroup}
83 84
 			</if>
84 85
 			<if test="jobId gt 0">
@@ -95,12 +96,13 @@
95 96
 			</if>
96 97
 			<if test="logStatus == 2" >
97 98
 				AND (
98
-				(t.trigger_code <![CDATA[ > ]]> 0 AND t.trigger_code!=200) ||
99
-				(t.handle_code <![CDATA[ > ]]> 0 AND t.handle_code!=200)
99
+					t.trigger_code NOT IN (0, 200) OR
100
+					t.handle_code NOT IN (0, 200)
100 101
 				)
101 102
 			</if>
102 103
 			<if test="logStatus == 3" >
103
-				AND (t.trigger_code = 200 AND t.handle_code=0)
104
+				AND t.trigger_code = 200
105
+				AND t.handle_code = 0
104 106
 			</if>
105 107
 		</trim>
106 108
 	</select>
@@ -115,10 +117,14 @@
115 117
 	<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
116 118
 		INSERT INTO XXL_JOB_QRTZ_TRIGGER_LOG (
117 119
 			`job_group`,
118
-			`job_id`
120
+			`job_id`,
121
+			`trigger_code`,
122
+			`handle_code`
119 123
 		) VALUES (
120 124
 			#{jobGroup},
121
-			#{jobId}
125
+			#{jobId},
126
+			#{triggerCode},
127
+			#{handleCode}
122 128
 		);
123 129
 		<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
124 130
 			SELECT LAST_INSERT_ID() 
@@ -166,7 +172,7 @@
166 172
 		SELECT
167 173
 			DATE_FORMAT(trigger_time,'%Y-%m-%d') triggerDay,
168 174
 			COUNT(handle_code) triggerDayCount,
169
-			SUM(CASE WHEN handle_code = 0 then 1 else 0 end) as triggerDayCountRunning,
175
+			SUM(CASE WHEN (trigger_code = 200 and handle_code = 0) then 1 else 0 end) as triggerDayCountRunning,
170 176
 			SUM(CASE WHEN handle_code = 200 then 1 else 0 end) as triggerDayCountSuc
171 177
 		FROM XXL_JOB_QRTZ_TRIGGER_LOG
172 178
 		WHERE trigger_time BETWEEN #{from} and #{to}

+ 1 - 0
xxl-job-admin/src/main/resources/xxl-job-admin.properties 查看文件

@@ -7,6 +7,7 @@ xxl.job.db.password=root_pwd
7 7
 ### xxl-job email
8 8
 xxl.job.mail.host=smtp.163.com
9 9
 xxl.job.mail.port=25
10
+xxl.job.mail.ssl=false
10 11
 xxl.job.mail.username=ovono802302@163.com
11 12
 xxl.job.mail.password=asdfzxcv
12 13
 xxl.job.mail.sendNick=《任务调度平台XXL-JOB》

+ 2 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl 查看文件

@@ -135,7 +135,7 @@
135 135
 								</#list>
136 136
                             </select>
137 137
                         </div>
138
-                        <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="black">*</font></label>
138
+                        <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
139 139
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
140 140
                     </div>
141 141
                     <div class="form-group">
@@ -308,7 +308,7 @@ process.exit(0)
308 308
 							</#list>
309 309
                             </select>
310 310
                         </div>
311
-                        <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="black">*</font></label>
311
+                        <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
312 312
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
313 313
                     </div>
314 314
                     <div class="form-group">

+ 1 - 1
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js 查看文件

@@ -229,7 +229,7 @@ $(function() {
229 229
 							end: function(layero, index){
230 230
 								if (needFresh) {
231 231
 									//window.location.reload();
232
-									jobTable.fnDraw();
232
+									jobTable.fnDraw(false);
233 233
 								}
234 234
 							}
235 235
 						});

+ 1 - 1
xxl-job-admin/src/test/java/com/xxl/job/admin/util/MailUtilTest.java 查看文件

@@ -18,7 +18,7 @@ import java.text.MessageFormat;
18 18
 public class MailUtilTest {
19 19
 
20 20
     @Test
21
-    public void registryTest() throws Exception {
21
+    public void mailTest() throws Exception {
22 22
 
23 23
         String mailBodyTemplate = "<h5>监控告警明细:</span>" +
24 24
                 "<table border=\"1\" cellpadding=\"3\" style=\"border-collapse:collapse; width:80%;\" >\n" +

+ 8 - 0
xxl-job-core/src/main/java/com/xxl/job/core/biz/AdminBiz.java 查看文件

@@ -13,6 +13,9 @@ public interface AdminBiz {
13 13
 
14 14
     public static final String MAPPING = "/api";
15 15
 
16
+
17
+    // ---------------------- callback ----------------------
18
+
16 19
     /**
17 20
      * callback
18 21
      *
@@ -21,6 +24,9 @@ public interface AdminBiz {
21 24
      */
22 25
     public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList);
23 26
 
27
+
28
+    // ---------------------- registry ----------------------
29
+
24 30
     /**
25 31
      * registry
26 32
      *
@@ -38,6 +44,8 @@ public interface AdminBiz {
38 44
     public ReturnT<String> registryRemove(RegistryParam registryParam);
39 45
 
40 46
 
47
+    // ---------------------- job opt ----------------------
48
+
41 49
     /**
42 50
      * trigger job for once
43 51
      *

+ 14 - 1
xxl-job-core/src/main/java/com/xxl/job/core/biz/model/HandleCallbackParam.java 查看文件

@@ -9,11 +9,14 @@ public class HandleCallbackParam implements Serializable {
9 9
     private static final long serialVersionUID = 42L;
10 10
 
11 11
     private int logId;
12
+    private long logDateTim;
13
+
12 14
     private ReturnT<String> executeResult;
13 15
 
14 16
     public HandleCallbackParam(){}
15
-    public HandleCallbackParam(int logId, ReturnT<String> executeResult) {
17
+    public HandleCallbackParam(int logId, long logDateTim, ReturnT<String> executeResult) {
16 18
         this.logId = logId;
19
+        this.logDateTim = logDateTim;
17 20
         this.executeResult = executeResult;
18 21
     }
19 22
 
@@ -25,6 +28,14 @@ public class HandleCallbackParam implements Serializable {
25 28
         this.logId = logId;
26 29
     }
27 30
 
31
+    public long getLogDateTim() {
32
+        return logDateTim;
33
+    }
34
+
35
+    public void setLogDateTim(long logDateTim) {
36
+        this.logDateTim = logDateTim;
37
+    }
38
+
28 39
     public ReturnT<String> getExecuteResult() {
29 40
         return executeResult;
30 41
     }
@@ -37,7 +48,9 @@ public class HandleCallbackParam implements Serializable {
37 48
     public String toString() {
38 49
         return "HandleCallbackParam{" +
39 50
                 "logId=" + logId +
51
+                ", logDateTim=" + logDateTim +
40 52
                 ", executeResult=" + executeResult +
41 53
                 '}';
42 54
     }
55
+
43 56
 }

+ 8 - 4
xxl-job-core/src/main/java/com/xxl/job/core/enums/ExecutorBlockStrategyEnum.java 查看文件

@@ -5,15 +5,19 @@ package com.xxl.job.core.enums;
5 5
  */
6 6
 public enum ExecutorBlockStrategyEnum {
7 7
 
8
-    SERIAL_EXECUTION("单机串行"),
8
+    SERIAL_EXECUTION("Serial execution"),
9 9
     /*CONCURRENT_EXECUTION("并行"),*/
10
-    DISCARD_LATER("丢弃后续调度"),
11
-    COVER_EARLY("覆盖之前调度");
10
+    DISCARD_LATER("Discard Later"),
11
+    COVER_EARLY("Cover Early");
12 12
 
13
-    private final String title;
13
+    private String title;
14 14
     private ExecutorBlockStrategyEnum (String title) {
15 15
         this.title = title;
16 16
     }
17
+
18
+    public void setTitle(String title) {
19
+        this.title = title;
20
+    }
17 21
     public String getTitle() {
18 22
         return title;
19 23
     }

+ 5 - 5
xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueTypeEnum.java 查看文件

@@ -5,11 +5,11 @@ package com.xxl.job.core.glue;
5 5
  */
6 6
 public enum GlueTypeEnum {
7 7
 
8
-    BEAN("BEAN模式", false, null, null),
9
-    GLUE_GROOVY("GLUE模式(Java)", false, null, null),
10
-    GLUE_SHELL("GLUE模式(Shell)", true, "bash", ".sh"),
11
-    GLUE_PYTHON("GLUE模式(Python)", true, "python", ".py"),
12
-    GLUE_NODEJS("GLUE模式(Nodejs)", true, "node", ".js");
8
+    BEAN("BEAN", false, null, null),
9
+    GLUE_GROOVY("GLUE(Java)", false, null, null),
10
+    GLUE_SHELL("GLUE(Shell)", true, "bash", ".sh"),
11
+    GLUE_PYTHON("GLUE(Python)", true, "python", ".py"),
12
+    GLUE_NODEJS("GLUE(Nodejs)", true, "node", ".js");
13 13
 
14 14
     private String desc;
15 15
     private boolean isScript;

+ 12 - 3
xxl-job-core/src/main/java/com/xxl/job/core/handler/impl/ScriptJobHandler.java 查看文件

@@ -8,6 +8,8 @@ import com.xxl.job.core.log.XxlJobLogger;
8 8
 import com.xxl.job.core.util.ScriptUtil;
9 9
 import com.xxl.job.core.util.ShardingUtil;
10 10
 
11
+import java.io.File;
12
+
11 13
 /**
12 14
  * Created by xuxueli on 17/4/27.
13 15
  */
@@ -41,7 +43,7 @@ public class ScriptJobHandler extends IJobHandler {
41 43
 
42 44
         // make script file
43 45
         String scriptFileName = XxlJobFileAppender.getGlueSrcPath()
44
-                .concat("/")
46
+                .concat(File.separator)
45 47
                 .concat(String.valueOf(jobId))
46 48
                 .concat("_")
47 49
                 .concat(String.valueOf(glueUpdatetime))
@@ -61,8 +63,15 @@ public class ScriptJobHandler extends IJobHandler {
61 63
         // invoke
62 64
         XxlJobLogger.log("----------- script file:"+ scriptFileName +" -----------");
63 65
         int exitValue = ScriptUtil.execToFile(cmd, scriptFileName, logFileName, scriptParams);
64
-        ReturnT<String> result = (exitValue==0)?IJobHandler.SUCCESS:new ReturnT<String>(IJobHandler.FAIL.getCode(), "script exit value("+exitValue+") is failed");
65
-        return result;
66
+
67
+        if (exitValue == 0) {
68
+            return IJobHandler.SUCCESS;
69
+        } else if (exitValue == 101) {
70
+            return IJobHandler.FAIL_RETRY;
71
+        } else {
72
+            return new ReturnT<String>(IJobHandler.FAIL.getCode(), "script exit value("+exitValue+") is failed");
73
+        }
74
+
66 75
     }
67 76
 
68 77
 }

+ 13 - 15
xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java 查看文件

@@ -79,7 +79,7 @@ public class XxlJobFileAppender {
79 79
 
80 80
 		// filePath/yyyy-MM-dd/9999.log
81 81
 		String logFileName = logFilePath.getPath()
82
-				.concat("/")
82
+				.concat(File.separator)
83 83
 				.concat(String.valueOf(logId))
84 84
 				.concat(".log");
85 85
 		return logFileName;
@@ -115,23 +115,21 @@ public class XxlJobFileAppender {
115 115
 		appendLog += "\r\n";
116 116
 		
117 117
 		// append file content
118
+		FileOutputStream fos = null;
118 119
 		try {
119
-			FileOutputStream fos = null;
120
-			try {
121
-				fos = new FileOutputStream(logFile, true);
122
-				fos.write(appendLog.getBytes("utf-8"));
123
-				fos.flush();
124
-			} finally {
125
-				if (fos != null) {
126
-					try {
127
-						fos.close();
128
-					} catch (IOException e) {
129
-						logger.error(e.getMessage(), e);
130
-					}
131
-				}
132
-			} 
120
+			fos = new FileOutputStream(logFile, true);
121
+			fos.write(appendLog.getBytes("utf-8"));
122
+			fos.flush();
133 123
 		} catch (Exception e) {
134 124
 			logger.error(e.getMessage(), e);
125
+		} finally {
126
+			if (fos != null) {
127
+				try {
128
+					fos.close();
129
+				} catch (IOException e) {
130
+					logger.error(e.getMessage(), e);
131
+				}
132
+			}
135 133
 		}
136 134
 		
137 135
 	}

+ 8 - 4
xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobLogger.java 查看文件

@@ -2,10 +2,11 @@ package com.xxl.job.core.log;
2 2
 
3 3
 import org.slf4j.Logger;
4 4
 import org.slf4j.LoggerFactory;
5
+import org.slf4j.helpers.FormattingTuple;
6
+import org.slf4j.helpers.MessageFormatter;
5 7
 
6 8
 import java.io.PrintWriter;
7 9
 import java.io.StringWriter;
8
-import java.text.MessageFormat;
9 10
 import java.text.SimpleDateFormat;
10 11
 import java.util.Date;
11 12
 
@@ -49,15 +50,18 @@ public class XxlJobLogger {
49 50
     /**
50 51
      * append log with pattern
51 52
      *
52
-     * @param appendLogPattern  like "aaa {0} bbb {1} ccc"
53
+     * @param appendLogPattern  like "aaa {} bbb {} ccc"
53 54
      * @param appendLogArguments    like "111, true"
54 55
      */
55 56
     public static void log(String appendLogPattern, Object ... appendLogArguments) {
56 57
 
57
-        String appendLog = appendLogPattern;
58
+    	FormattingTuple ft = MessageFormatter.format(appendLogPattern, appendLogArguments);
59
+        String appendLog = ft.getMessage();
60
+
61
+        /*appendLog = appendLogPattern;
58 62
         if (appendLogArguments!=null && appendLogArguments.length>0) {
59 63
             appendLog = MessageFormat.format(appendLogPattern, appendLogArguments);
60
-        }
64
+        }*/
61 65
 
62 66
         StackTraceElement callInfo = new Throwable().getStackTrace()[1];
63 67
         logDetail(callInfo, appendLog);

+ 1 - 2
xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/NetComClientProxy.java 查看文件

@@ -58,8 +58,7 @@ public class NetComClientProxy implements FactoryBean<Object> {
58 58
 	                    
59 59
 	                    // valid response
60 60
 						if (response == null) {
61
-							logger.error(">>>>>>>>>>> xxl-rpc netty response not found.");
62
-							throw new Exception(">>>>>>>>>>> xxl-rpc netty response not found.");
61
+							throw new Exception("Network request fail, response not found.");
63 62
 						}
64 63
 	                    if (response.isError()) {
65 64
 	                        throw new RuntimeException(response.getError());

+ 2 - 2
xxl-job-core/src/main/java/com/xxl/job/core/rpc/netcom/jetty/client/JettyClient.java 查看文件

@@ -29,7 +29,7 @@ public class JettyClient {
29 29
 			byte[] responseBytes = HttpClientUtil.postRequest(reqURL, requestBytes);
30 30
 			if (responseBytes == null || responseBytes.length==0) {
31 31
 				RpcResponse rpcResponse = new RpcResponse();
32
-				rpcResponse.setError("RpcResponse byte[] is null");
32
+				rpcResponse.setError("Network request fail, RpcResponse byte[] is null");
33 33
 				return rpcResponse;
34 34
             }
35 35
 
@@ -40,7 +40,7 @@ public class JettyClient {
40 40
 			logger.error(e.getMessage(), e);
41 41
 
42 42
 			RpcResponse rpcResponse = new RpcResponse();
43
-			rpcResponse.setError("Client-error:" + e.getMessage());
43
+			rpcResponse.setError("Network request error: " + e.getMessage());
44 44
 			return rpcResponse;
45 45
 		}
46 46
 	}

+ 14 - 8
xxl-job-core/src/main/java/com/xxl/job/core/thread/JobThread.java 查看文件

@@ -8,16 +8,22 @@ import com.xxl.job.core.handler.IJobHandler;
8 8
 import com.xxl.job.core.log.XxlJobFileAppender;
9 9
 import com.xxl.job.core.log.XxlJobLogger;
10 10
 import com.xxl.job.core.util.ShardingUtil;
11
-import org.eclipse.jetty.util.ConcurrentHashSet;
12 11
 import org.slf4j.Logger;
13 12
 import org.slf4j.LoggerFactory;
14 13
 
15 14
 import java.io.PrintWriter;
16 15
 import java.io.StringWriter;
17
-import java.util.Arrays;
16
+import java.util.Collections;
18 17
 import java.util.Date;
18
+
19 19
 import java.util.concurrent.*;
20 20
 
21
+import java.util.HashSet;
22
+import java.util.Set;
23
+import java.util.concurrent.LinkedBlockingQueue;
24
+import java.util.concurrent.TimeUnit;
25
+
26
+
21 27
 /**
22 28
  * handler thread
23 29
  * @author xuxueli 2016-1-16 19:52:47
@@ -28,9 +34,9 @@ public class JobThread extends Thread{
28 34
 	private int jobId;
29 35
 	private IJobHandler handler;
30 36
 	private LinkedBlockingQueue<TriggerParam> triggerQueue;
31
-	private ConcurrentHashSet<Integer> triggerLogIdSet;		// avoid repeat trigger for the same TRIGGER_LOG_ID
37
+	private Set<Integer> triggerLogIdSet;		// avoid repeat trigger for the same TRIGGER_LOG_ID
32 38
 
33
-	private boolean toStop = false;
39
+	private volatile boolean toStop = false;
34 40
 	private String stopReason;
35 41
 
36 42
     private boolean running = false;    // if running job
@@ -41,7 +47,7 @@ public class JobThread extends Thread{
41 47
 		this.jobId = jobId;
42 48
 		this.handler = handler;
43 49
 		this.triggerQueue = new LinkedBlockingQueue<TriggerParam>();
44
-		this.triggerLogIdSet = new ConcurrentHashSet<Integer>();
50
+		this.triggerLogIdSet = Collections.synchronizedSet(new HashSet<Integer>());
45 51
 	}
46 52
 	public IJobHandler getHandler() {
47 53
 		return handler;
@@ -171,11 +177,11 @@ public class JobThread extends Thread{
171 177
                     // callback handler info
172 178
                     if (!toStop) {
173 179
                         // commonm
174
-                        TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), executeResult));
180
+                        TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTim(), executeResult));
175 181
                     } else {
176 182
                         // is killed
177 183
                         ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [业务运行中,被强制终止]");
178
-                        TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), stopResult));
184
+                        TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTim(), stopResult));
179 185
                     }
180 186
                 }
181 187
             }
@@ -187,7 +193,7 @@ public class JobThread extends Thread{
187 193
 			if (triggerParam!=null) {
188 194
 				// is killed
189 195
 				ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [任务尚未执行,在调度队列中被终止]");
190
-				TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), stopResult));
196
+				TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTim(), stopResult));
191 197
 			}
192 198
 		}
193 199
 

+ 17 - 4
xxl-job-core/src/main/java/com/xxl/job/core/thread/TriggerCallbackThread.java 查看文件

@@ -4,10 +4,13 @@ import com.xxl.job.core.biz.AdminBiz;
4 4
 import com.xxl.job.core.biz.model.HandleCallbackParam;
5 5
 import com.xxl.job.core.biz.model.ReturnT;
6 6
 import com.xxl.job.core.executor.XxlJobExecutor;
7
+import com.xxl.job.core.log.XxlJobFileAppender;
8
+import com.xxl.job.core.log.XxlJobLogger;
7 9
 import org.slf4j.Logger;
8 10
 import org.slf4j.LoggerFactory;
9 11
 
10 12
 import java.util.ArrayList;
13
+import java.util.Date;
11 14
 import java.util.List;
12 15
 import java.util.concurrent.LinkedBlockingQueue;
13 16
 
@@ -108,17 +111,27 @@ public class TriggerCallbackThread {
108 111
             try {
109 112
                 ReturnT<String> callbackResult = adminBiz.callback(callbackParamList);
110 113
                 if (callbackResult!=null && ReturnT.SUCCESS_CODE == callbackResult.getCode()) {
111
-                    callbackResult = ReturnT.SUCCESS;
112
-                    logger.info(">>>>>>>>>>> xxl-job callback success, callbackParamList:{}, callbackResult:{}", new Object[]{callbackParamList, callbackResult});
114
+                    callbackLog(callbackParamList, "<br>----------- xxl-job callback success");
113 115
                     break;
114 116
                 } else {
115
-                    logger.info(">>>>>>>>>>> xxl-job callback fail, callbackParamList:{}, callbackResult:{}", new Object[]{callbackParamList, callbackResult});
117
+                    callbackLog(callbackParamList, "<br>----------- xxl-job callback fail, callbackResult:" + callbackResult);
116 118
                 }
117 119
             } catch (Exception e) {
118
-                logger.error(">>>>>>>>>>> xxl-job callback error, callbackParamList:{}", callbackParamList, e);
120
+                callbackLog(callbackParamList, "<br>----------- xxl-job callback error, errorMsg:" + e.getMessage());
119 121
                 //getInstance().callBackQueue.addAll(callbackParamList);
120 122
             }
121 123
         }
122 124
     }
123 125
 
126
+    /**
127
+     * callback log
128
+     */
129
+    private void callbackLog(List<HandleCallbackParam> callbackParamList, String logContent){
130
+        for (HandleCallbackParam callbackParam: callbackParamList) {
131
+            String logFileName = XxlJobFileAppender.makeLogFileName(new Date(callbackParam.getLogDateTim()), callbackParam.getLogId());
132
+            XxlJobFileAppender.contextHolder.set(logFileName);
133
+            XxlJobLogger.log(logContent);
134
+        }
135
+    }
136
+
124 137
 }

+ 3 - 4
xxl-job-core/src/main/java/com/xxl/job/core/util/HttpClientUtil.java 查看文件

@@ -26,7 +26,7 @@ public class HttpClientUtil {
26 26
 	/**
27 27
 	 * post request
28 28
 	 */
29
-	public static byte[] postRequest(String reqURL, byte[] date) throws Exception {
29
+	public static byte[] postRequest(String reqURL, byte[] data) throws Exception {
30 30
 		byte[] responseBytes = null;
31 31
 		
32 32
 		HttpPost httpPost = new HttpPost(reqURL);
@@ -53,8 +53,8 @@ public class HttpClientUtil {
53 53
 			httpPost.setConfig(requestConfig);
54 54
 
55 55
 			// data
56
-			if (date != null) {
57
-				httpPost.setEntity(new ByteArrayEntity(date, ContentType.DEFAULT_BINARY));
56
+			if (data != null) {
57
+				httpPost.setEntity(new ByteArrayEntity(data, ContentType.DEFAULT_BINARY));
58 58
 			}
59 59
 			// do post
60 60
 			HttpResponse response = httpClient.execute(httpPost);
@@ -64,7 +64,6 @@ public class HttpClientUtil {
64 64
 				EntityUtils.consume(entity);
65 65
 			}
66 66
 		} catch (Exception e) {
67
-			logger.error(e.getMessage(), e);
68 67
 			throw e;
69 68
 		} finally {
70 69
 			httpPost.releaseConnection();

+ 17 - 1
xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java 查看文件

@@ -1,5 +1,6 @@
1 1
 package com.xxl.job.core.util;
2 2
 
3
+import com.xxl.job.core.log.XxlJobLogger;
3 4
 import org.apache.commons.exec.CommandLine;
4 5
 import org.apache.commons.exec.DefaultExecutor;
5 6
 import org.apache.commons.exec.PumpStreamHandler;
@@ -59,7 +60,10 @@ public class ScriptUtil {
59 60
         // 标准输出:print (null if watchdog timeout)
60 61
         // 错误输出:logging + 异常 (still exists if watchdog timeout)
61 62
         // 标准输入
62
-        try (FileOutputStream fileOutputStream = new FileOutputStream(logFile, true)) {
63
+
64
+        FileOutputStream fileOutputStream = null;   //
65
+        try {
66
+            fileOutputStream = new FileOutputStream(logFile, true);
63 67
             PumpStreamHandler streamHandler = new PumpStreamHandler(fileOutputStream, fileOutputStream, null);
64 68
 
65 69
             // command
@@ -75,6 +79,18 @@ public class ScriptUtil {
75 79
             exec.setStreamHandler(streamHandler);
76 80
             int exitValue = exec.execute(commandline);  // exit code: 0=success, 1=error
77 81
             return exitValue;
82
+        } catch (Exception e) {
83
+            XxlJobLogger.log(e);
84
+            return -1;
85
+        } finally {
86
+            if (fileOutputStream != null) {
87
+                try {
88
+                    fileOutputStream.close();
89
+                } catch (IOException e) {
90
+                    XxlJobLogger.log(e);
91
+                }
92
+
93
+            }
78 94
         }
79 95
     }
80 96
 

+ 1 - 0
xxl-job-executor-samples/xxl-job-executor-sample-springboot/pom.xml 查看文件

@@ -84,6 +84,7 @@
84 84
             <plugin>
85 85
                 <groupId>org.springframework.boot</groupId>
86 86
                 <artifactId>spring-boot-maven-plugin</artifactId>
87
+                <version>${spring-boot.version}</version>
87 88
                 <executions>
88 89
                     <execution>
89 90
                         <goals>