diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 00000000..91106d3f
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,17 @@
+name: Java CI
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ - name: Build with Maven
+ run: mvn -B package --file pom.xml
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1f6eb26a..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: java
-jdk:
- - openjdk8
-install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true
-#script: mvn test
-script: mvn -DskipTests=true clean package
\ No newline at end of file
diff --git a/README.md b/README.md
index 1a741326..b4b17d68 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@
-- Home Page --
-
-
+
+
@@ -378,6 +378,16 @@ XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是
- 259、爱乐优(二手平台)
- 260、猫眼电影(私有化部署)【猫眼电影】
- 261、美团大象(私有化部署)【美团大象】
+ - 262、作业帮教育科技(北京)有限公司【作业帮】
+ - 263、北京小年糕互联网技术有限公司
+ - 264、山东矩阵软件工程股份有限公司
+ - 265、陕西国驿软件科技有限公司
+ - 266、君开信息科技
+ - 267、村鸟网络科技有限责任公司
+ - 268、云南国际信托有限公司
+ - 269、金智教育
+ - 270、珠海市筑巢科技有限公司
+ - 271、上海百胜软件股份有限公司
- ……
> 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。
diff --git a/doc/XXL-JOB-English-Documentation.md b/doc/XXL-JOB-English-Documentation.md
index 8351f6aa..d3c20fae 100644
--- a/doc/XXL-JOB-English-Documentation.md
+++ b/doc/XXL-JOB-English-Documentation.md
@@ -1,6 +1,6 @@
## 《Distributed task scheduling framework XXL-JOB》
-[![Build Status](https://travis-ci.org/xuxueli/xxl-job.svg?branch=master)](https://travis-ci.org/xuxueli/xxl-job)
+[![Actions Status](https://github.com/xuxueli/xxl-job/workflows/Java%20CI/badge.svg)](https://github.com/xuxueli/xxl-job/actions)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/)
[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases)
[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/doc/XXL-JOB官方文档.md b/doc/XXL-JOB官方文档.md
index 3eab136f..8c99c712 100644
--- a/doc/XXL-JOB官方文档.md
+++ b/doc/XXL-JOB官方文档.md
@@ -1,6 +1,6 @@
## 《分布式任务调度平台XXL-JOB》
-[![Build Status](https://travis-ci.org/xuxueli/xxl-job.svg?branch=master)](https://travis-ci.org/xuxueli/xxl-job)
+[![Actions Status](https://github.com/xuxueli/xxl-job/workflows/Java%20CI/badge.svg)](https://github.com/xuxueli/xxl-job/actions)
[![Docker Status](https://img.shields.io/badge/docker-passing-brightgreen.svg)](https://hub.docker.com/r/xuxueli/xxl-job-admin/)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/)
[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases)
@@ -346,6 +346,16 @@ XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是
- 259、爱乐优(二手平台)
- 260、猫眼电影(私有化部署)【猫眼电影】
- 261、美团大象(私有化部署)【美团大象】
+ - 262、作业帮教育科技(北京)有限公司【作业帮】
+ - 263、北京小年糕互联网技术有限公司
+ - 264、山东矩阵软件工程股份有限公司
+ - 265、陕西国驿软件科技有限公司
+ - 266、君开信息科技
+ - 267、村鸟网络科技有限责任公司
+ - 268、云南国际信托有限公司
+ - 269、金智教育
+ - 270、珠海市筑巢科技有限公司
+ - 271、上海百胜软件股份有限公司
- ……
> 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。
@@ -383,7 +393,7 @@ XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是
### 1.6 环境
- Maven3+
- Jdk1.7+
-- Mysql5.6+
+- Mysql5.7+
## 二、快速入门
@@ -465,7 +475,6 @@ XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是
调度中心集群部署时,几点要求和建议:
- DB配置保持一致;
-- 登陆账号配置保持一致;
- 集群机器时钟保持一致(单机集群忽视);
- 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。
@@ -922,8 +931,8 @@ XXL-JOB的每个调度任务虽然在调度模块是并行调度执行的,但
任务调度错过触发时间时的处理策略:
- 可能原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过;
- 处理策略:
- - 过期超5s:本地忽略,当前时间开始计算下次触发时间
- - 过期超过5s:过期5s内:立即触发一次,当前时间开始计算下次触发时间
+ - 过期超5s:本次忽略,当前时间开始计算下次触发时间
+ - 过期5s内:立即触发一次,当前时间开始计算下次触发时间
#### 5.4.7 日志回调服务
@@ -990,6 +999,11 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
如若需要支撑更多的任务量,可以通过 "调大调度线程数" 、"降低调度中心与执行器ping延迟" 和 "提升机器配置" 几种方式优化。
+#### 5.4.12 均衡调度
+
+调度中心在集群部署时会自动进行任务平均分配,触发组件每次获取与线程池数量(调度中心支持自定义调度线程池大小)相关数量的任务,避免大量任务集中在单个调度中心集群节点;
+
+
### 5.5 任务 "运行模式" 剖析
#### 5.5.1 "Bean模式" 任务
开发步骤:可参考 "章节三" ;
@@ -1113,7 +1127,7 @@ API服务请求参考代码:com.xxl.job.adminbiz.AdminBizTest.java
7、任务触发;
API服务位置:com.xxl.job.admin.controller.JobInfoController.java
-API服务请求参考代码:可参考任务界面操作的ajax请求。任何ajax接口均可配置成为API服务,只需在待启用的API服务上添加 “@PermessionLimit(limit = false)” 注解取消登陆态拦截即可;
+API服务请求参考代码:可参考任务界面操作的ajax请求。任何ajax接口均可配置成为API服务,只需在待启用的API服务上添加 “@PermissionLimit(limit = false)” 注解取消登陆态拦截即可;
### 5.12 执行器API服务
执行器提供了API服务,供调度中心选择使用,目前提供的API服务有:
@@ -1563,15 +1577,21 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
- 6、调度组件优化:针对永远不会触发的Cron禁止配置和启动;任务Cron最后一次触发后再也不会触发时,比如一次性任务,主动停止相关任务;
- 7、任务列表交互优化,支持查看任务所属执行器的注册节点;
- 8、DB重连优化,修复DB宕机重连后任务调度停止的问题,重连后自动加入调度集群触发任务调度;
-- 9、任务触发组件加载顺序调整,避免小概率情况下组件随机加载顺序导致的I18N的NPE问题。
+- 9、任务触发组件加载顺序调整,避免小概率情况下组件随机加载顺序导致的I18N的NPE问题;
- 10、项目依赖升级至较新稳定版本,如spring、spring-boot、mybatis、slf4j、groovy等等;
- 11、JobThread自销毁优化,避免并发触发导致triggerQueue中任务丢失问题;
-- 12、[ING,交互兼容问题待处理]Cron在线生成工具:任务新增、编辑框通过组件在线生成Cron表达式;
+- 12、Cron在线生成工具:任务新增、编辑框通过组件在线生成Cron表达式;
- 13、Cron下次执行时间查询:支持通过界面在线查看后续连续5次执行时间;
- 14、任务重试时参数丢失的问题修复;
-- 15、[ING]xxl-rpc服务端线程优化,降低线程内存开销;
-- 16、[ING]调度日志优化:支持设置日志保留天数,过期日志天维度记录报表,并清理;调度报表汇总实时数据和报表;
-- 17、[ING]父子任务参数传递;流程任务等,透传动态参数;
+- 15、调度中心密码限制18位,修复修改密码超过18位无法登陆的问题;
+- 16、任务告警组件分页参数无效问题修复;
+- 17、DB脚本默认编码改为utf8mb4,修复字符乱码问题(建议Mysql版本5.7+);
+- 18、调度中心任务平均分配,触发组件每次获取与线程池数量相关数量的任务,避免大量任务集中在单个调度中心集群节点;
+- 19、调度中心移除SQL中的 "now()" 函数;集群部署时不再依赖DB时钟,仅需要保证调度中心应用节点时钟一致即可;
+- 20、xxl-rpc服务端线程优化,降低线程内存开销;
+- 21、调度中心回调API服务改为restful方式;
+- 22、[ING]调度日志优化:支持设置日志保留天数,过期日志天维度记录报表,并清理;调度报表汇总实时数据和报表;
+- 23、[ING]调度中心日志删除,改为分页获取ID,根据ID删除的方式;
@@ -1589,7 +1609,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
- 11、失败重试间隔;
- 12、SimpleTrigger:除Cron外,支持设置固定时间间隔触发;
- 13、调度日志列表加上执行时长列,并支持排序;
-- 14、DAG流程任务:替换子任务,支持参数传递:配置并列的"a-b、b-c"路径列表,构成串行、并行、dag任务流程,"dagre-d3"绘图;任务依赖,流程图,子任务+会签任务,各节点日志;
+- 14、DAG流程任务:替换子任务,支持参数传递:配置并列的"a-b、b-c"路径列表,构成串行、并行、dag任务流程,"dagre-d3"绘图;任务依赖,流程图,子任务+会签任务,各节点日志;支持根据成功、失败选择分支;
- 15、日期过滤:支持多个时间段排除;
- 16、告警邮件内容,支持自定义模板配置;
- 17、暂停状态,支持Cron 为空;
@@ -1604,6 +1624,14 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
- 26、调度中心JDK版本调整为JDK8,从而升级至最新版本SpringBoot;
- 27、执行器服务端口与注册端口分离,支持docker动态随机端口;
- 28、执行器端口复用,复用容器端口提供通讯服务;
+- 29、自定义失败重试时间间隔;
+- 30、分片任务全部成功后触发子任务;
+- 31、任务复制功能;点击复制是弹出新建任务弹框,并初始化被复制任务信息;
+- 32、AccessToken按照执行器维度设置;控制调度、回调;
+- 33、任务执行一次的时候指定IP;
+- 34、通讯调整;双向HTTP,回调和其他API自定义AccessToken,Restful,执行器复用容器端口;
+- 35、父子任务参数传递;流程任务等,透传动态参数;
+- 36、任务操作API服务调整为和回调服务一致,降低接入成本;
## 七、其他
diff --git a/doc/db/tables_xxl_job.sql b/doc/db/tables_xxl_job.sql
index 783df0cb..c6c5386d 100644
--- a/doc/db/tables_xxl_job.sql
+++ b/doc/db/tables_xxl_job.sql
@@ -2,7 +2,7 @@
# XXL-JOB v2.1.1-SNAPSHOT
# Copyright (c) 2015-present, xuxueli.
-CREATE database if NOT EXISTS `xxl_job` default character set utf8 collate utf8_general_ci;
+CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci;
use `xxl_job`;
@@ -30,7 +30,7 @@ CREATE TABLE `xxl_job_info` (
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
@@ -51,7 +51,7 @@ CREATE TABLE `xxl_job_log` (
PRIMARY KEY (`id`),
KEY `I_trigger_time` (`trigger_time`),
KEY `I_handle_code` (`handle_code`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_logglue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -59,20 +59,20 @@ CREATE TABLE `xxl_job_logglue` (
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
- `add_time` timestamp NULL DEFAULT NULL,
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+ `add_time` datetime DEFAULT NULL,
+ `update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_registry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
- `registry_group` varchar(255) NOT NULL,
+ `registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -82,7 +82,7 @@ CREATE TABLE `xxl_job_group` (
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
`address_list` varchar(512) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -92,12 +92,12 @@ CREATE TABLE `xxl_job_user` (
`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
PRIMARY KEY (`id`),
UNIQUE KEY `i_username` (`username`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) NOT NULL COMMENT '锁名称',
PRIMARY KEY (`lock_name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `order`, `address_type`, `address_list`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 1, 0, NULL);
diff --git a/pom.xml b/pom.xml
index 74530394..8351b0db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
1.7
true
- 1.4.1
+ 1.4.2
4.3.25.RELEASE
1.5.22.RELEASE
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java
index 23dc406f..7611b810 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java
@@ -1,34 +1,97 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
-import com.xxl.job.admin.core.conf.XxlJobScheduler;
+import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.core.biz.AdminBiz;
-import org.springframework.beans.factory.InitializingBean;
+import com.xxl.job.core.biz.model.HandleCallbackParam;
+import com.xxl.job.core.biz.model.RegistryParam;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.util.XxlJobRemotingUtil;
import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
-import javax.servlet.ServletException;
+import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
+import java.util.List;
/**
* Created by xuxueli on 17/5/10.
*/
@Controller
-public class JobApiController implements InitializingBean {
+@RequestMapping("/api")
+public class JobApiController {
+ @Resource
+ private AdminBiz adminBiz;
- @Override
- public void afterPropertiesSet() {
+ // ---------------------- admin biz ----------------------
+
+ /**
+ * callback
+ *
+ * @param callbackParamList
+ * @return
+ */
+ @RequestMapping("/callback")
+ @ResponseBody
+ @PermissionLimit(limit=false)
+ public ReturnT callback(HttpServletRequest request, @RequestBody List callbackParamList) {
+
+ if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null
+ && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0
+ && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_RPC_ACCESS_TOKEN))) {
+ return new ReturnT(ReturnT.FAIL_CODE, "The access token is wrong.");
+ }
+
+ return adminBiz.callback(callbackParamList);
+ }
+
+
+
+ /**
+ * registry
+ *
+ * @param registryParam
+ * @return
+ */
+ @RequestMapping("/registry")
+ @ResponseBody
+ @PermissionLimit(limit=false)
+ public ReturnT registry(HttpServletRequest request, @RequestBody RegistryParam registryParam) {
+
+ if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null
+ && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0
+ && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_RPC_ACCESS_TOKEN))) {
+ return new ReturnT(ReturnT.FAIL_CODE, "The access token is wrong.");
+ }
+
+ return adminBiz.registry(registryParam);
}
- @RequestMapping(AdminBiz.MAPPING)
+ /**
+ * registry remove
+ *
+ * @param registryParam
+ * @return
+ */
+ @RequestMapping("/registryRemove")
+ @ResponseBody
@PermissionLimit(limit=false)
- public void api(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- XxlJobScheduler.invokeAdminService(request, response);
+ public ReturnT registryRemove(HttpServletRequest request, @RequestBody RegistryParam registryParam) {
+
+ if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null
+ && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0
+ && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_RPC_ACCESS_TOKEN))) {
+ return new ReturnT(ReturnT.FAIL_CODE, "The access token is wrong.");
+ }
+
+ return adminBiz.registryRemove(registryParam);
}
+ // ---------------------- job biz ----------------------
+
}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java
index 7fbf35b5..302b9bf9 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java
@@ -72,6 +72,8 @@ public class JobCodeController {
exists_jobInfo.setGlueSource(glueSource);
exists_jobInfo.setGlueRemark(glueRemark);
exists_jobInfo.setGlueUpdatetime(new Date());
+
+ exists_jobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(exists_jobInfo);
// log old code
@@ -80,6 +82,9 @@ public class JobCodeController {
xxlJobLogGlue.setGlueType(exists_jobInfo.getGlueType());
xxlJobLogGlue.setGlueSource(glueSource);
xxlJobLogGlue.setGlueRemark(glueRemark);
+
+ xxlJobLogGlue.setAddTime(new Date());
+ xxlJobLogGlue.setUpdateTime(new Date());
xxlJobLogGlueDao.save(xxlJobLogGlue);
// remove code backup more than 30
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java
index bb130f65..9376eb75 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java
@@ -14,10 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
/**
* job group controller
@@ -119,7 +116,7 @@ public class JobGroupController {
private List findRegistryByAppName(String appNameParam){
HashMap> appAddressMap = new HashMap>();
- List list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT);
+ List list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item: list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
index a32e71af..016b0169 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
@@ -1,6 +1,6 @@
package com.xxl.job.admin.controller;
-import com.xxl.job.admin.core.conf.XxlJobScheduler;
+import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
index 68dd1fa1..b7224a62 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
@@ -1,10 +1,11 @@
package com.xxl.job.admin.core.conf;
+import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobInfoDao;
import com.xxl.job.admin.dao.XxlJobLogDao;
import com.xxl.job.admin.dao.XxlJobRegistryDao;
-import com.xxl.job.core.biz.AdminBiz;
+import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
@@ -18,18 +19,36 @@ import javax.sql.DataSource;
*
* @author xuxueli 2017-04-28
*/
+
@Component
-public class XxlJobAdminConfig implements InitializingBean{
+public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
+
private static XxlJobAdminConfig adminConfig = null;
public static XxlJobAdminConfig getAdminConfig() {
return adminConfig;
}
+
+ // ---------------------- XxlJobScheduler ----------------------
+
+ private XxlJobScheduler xxlJobScheduler;
+
@Override
public void afterPropertiesSet() {
adminConfig = this;
+
+ xxlJobScheduler = new XxlJobScheduler();
+ xxlJobScheduler.init();
}
+ @Override
+ public void destroy() throws Exception {
+ xxlJobScheduler.destroy();
+ }
+
+
+ // ---------------------- XxlJobScheduler ----------------------
+
// conf
@Value("${xxl.job.i18n}")
private String i18n;
@@ -40,6 +59,12 @@ public class XxlJobAdminConfig implements InitializingBean{
@Value("${spring.mail.username}")
private String emailUserName;
+ @Value("${xxl.job.triggerpool.fast.max}")
+ private int triggerPoolFastMax;
+
+ @Value("${xxl.job.triggerpool.slow.max}")
+ private int triggerPoolSlowMax;
+
// dao, service
@Resource
@@ -51,8 +76,6 @@ public class XxlJobAdminConfig implements InitializingBean{
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
- private AdminBiz adminBiz;
- @Resource
private JavaMailSender mailSender;
@Resource
private DataSource dataSource;
@@ -70,6 +93,20 @@ public class XxlJobAdminConfig implements InitializingBean{
return emailUserName;
}
+ public int getTriggerPoolFastMax() {
+ if (triggerPoolFastMax < 200) {
+ return 200;
+ }
+ return triggerPoolFastMax;
+ }
+
+ public int getTriggerPoolSlowMax() {
+ if (triggerPoolSlowMax < 100) {
+ return 100;
+ }
+ return triggerPoolSlowMax;
+ }
+
public XxlJobLogDao getXxlJobLogDao() {
return xxlJobLogDao;
}
@@ -86,10 +123,6 @@ public class XxlJobAdminConfig implements InitializingBean{
return xxlJobGroupDao;
}
- public AdminBiz getAdminBiz() {
- return adminBiz;
- }
-
public JavaMailSender getMailSender() {
return mailSender;
}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobScheduler.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobScheduler.java
deleted file mode 100644
index 11e3ad62..00000000
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobScheduler.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package com.xxl.job.admin.core.conf;
-
-import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
-import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper;
-import com.xxl.job.admin.core.thread.JobScheduleHelper;
-import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
-import com.xxl.job.admin.core.util.I18nUtil;
-import com.xxl.job.core.biz.AdminBiz;
-import com.xxl.job.core.biz.ExecutorBiz;
-import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
-import com.xxl.rpc.remoting.invoker.XxlRpcInvokerFactory;
-import com.xxl.rpc.remoting.invoker.call.CallType;
-import com.xxl.rpc.remoting.invoker.reference.XxlRpcReferenceBean;
-import com.xxl.rpc.remoting.invoker.route.LoadBalance;
-import com.xxl.rpc.remoting.net.NetEnum;
-import com.xxl.rpc.remoting.net.impl.servlet.server.ServletServerHandler;
-import com.xxl.rpc.remoting.provider.XxlRpcProviderFactory;
-import com.xxl.rpc.serialize.Serializer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.annotation.DependsOn;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * @author xuxueli 2018-10-28 00:18:17
- */
-@Component
-@DependsOn("xxlJobAdminConfig")
-public class XxlJobScheduler implements InitializingBean, DisposableBean {
- private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class);
-
-
- @Override
- public void afterPropertiesSet() {
- // init i18n
- initI18n();
-
- // admin registry monitor run
- JobRegistryMonitorHelper.getInstance().start();
-
- // admin monitor run
- JobFailMonitorHelper.getInstance().start();
-
- // admin-server
- initRpcProvider();
-
- // start-schedule
- JobScheduleHelper.getInstance().start();
-
- logger.info(">>>>>>>>> init xxl-job admin success.");
- }
-
- @Override
- public void destroy() throws Exception {
-
- // stop-schedule
- JobScheduleHelper.getInstance().toStop();
-
- // admin trigger pool stop
- JobTriggerPoolHelper.toStop();
-
- // admin registry stop
- JobRegistryMonitorHelper.getInstance().toStop();
-
- // admin monitor stop
- JobFailMonitorHelper.getInstance().toStop();
-
- // admin-server
- stopRpcProvider();
- }
-
- // ---------------------- I18n ----------------------
-
- private void initI18n(){
- for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
- item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
- }
- }
-
- // ---------------------- admin rpc provider (no server version) ----------------------
- private static ServletServerHandler servletServerHandler;
- private void initRpcProvider(){
- // init
- XxlRpcProviderFactory xxlRpcProviderFactory = new XxlRpcProviderFactory();
- xxlRpcProviderFactory.initConfig(
- NetEnum.NETTY_HTTP,
- Serializer.SerializeEnum.HESSIAN.getSerializer(),
- null,
- 0,
- XxlJobAdminConfig.getAdminConfig().getAccessToken(),
- null,
- null);
-
- // add services
- xxlRpcProviderFactory.addService(AdminBiz.class.getName(), null, XxlJobAdminConfig.getAdminConfig().getAdminBiz());
-
- // servlet handler
- servletServerHandler = new ServletServerHandler(xxlRpcProviderFactory);
- }
- private void stopRpcProvider() throws Exception {
- XxlRpcInvokerFactory.getInstance().stop();
- }
- public static void invokeAdminService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- servletServerHandler.handle(null, request, response);
- }
-
-
- // ---------------------- executor-client ----------------------
- private static ConcurrentMap executorBizRepository = new ConcurrentHashMap();
- public static ExecutorBiz getExecutorBiz(String address) {
- // valid
- if (address==null || address.trim().length()==0) {
- return null;
- }
-
- // load-cache
- address = address.trim();
- ExecutorBiz executorBiz = executorBizRepository.get(address);
- if (executorBiz != null) {
- return executorBiz;
- }
-
- // set-cache
- executorBiz = (ExecutorBiz) new XxlRpcReferenceBean(
- NetEnum.NETTY_HTTP,
- Serializer.SerializeEnum.HESSIAN.getSerializer(),
- CallType.SYNC,
- LoadBalance.ROUND,
- ExecutorBiz.class,
- null,
- 3000,
- address,
- XxlJobAdminConfig.getAdminConfig().getAccessToken(),
- null,
- null).getObject();
-
- executorBizRepository.put(address, executorBiz);
- return executorBiz;
- }
-
-}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java
index c617d425..7b1ca461 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java
@@ -1,5 +1,7 @@
package com.xxl.job.admin.core.model;
+import java.util.Date;
+
/**
* xxl-job log for glue, used to track job code process
* @author xuxueli 2016-5-19 17:57:46
@@ -11,8 +13,8 @@ public class XxlJobLogGlue {
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
private String glueSource;
private String glueRemark;
- private String addTime;
- private String updateTime;
+ private Date addTime;
+ private Date updateTime;
public int getId() {
return id;
@@ -54,19 +56,19 @@ public class XxlJobLogGlue {
this.glueRemark = glueRemark;
}
- public String getAddTime() {
+ public Date getAddTime() {
return addTime;
}
- public void setAddTime(String addTime) {
+ public void setAddTime(Date addTime) {
this.addTime = addTime;
}
- public String getUpdateTime() {
+ public Date getUpdateTime() {
return updateTime;
}
- public void setUpdateTime(String updateTime) {
+ public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
index 992b4ceb..26015991 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
@@ -1,6 +1,6 @@
package com.xxl.job.admin.core.route.strategy;
-import com.xxl.job.admin.core.conf.XxlJobScheduler;
+import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.ExecutorBiz;
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
index 26aaa067..a2e4c909 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
@@ -1,6 +1,6 @@
package com.xxl.job.admin.core.route.strategy;
-import com.xxl.job.admin.core.conf.XxlJobScheduler;
+import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.ExecutorBiz;
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java
new file mode 100644
index 00000000..bb2526ea
--- /dev/null
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java
@@ -0,0 +1,109 @@
+package com.xxl.job.admin.core.scheduler;
+
+import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
+import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
+import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper;
+import com.xxl.job.admin.core.thread.JobScheduleHelper;
+import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
+import com.xxl.job.admin.core.util.I18nUtil;
+import com.xxl.job.core.biz.ExecutorBiz;
+import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
+import com.xxl.rpc.remoting.invoker.call.CallType;
+import com.xxl.rpc.remoting.invoker.reference.XxlRpcReferenceBean;
+import com.xxl.rpc.remoting.invoker.route.LoadBalance;
+import com.xxl.rpc.remoting.net.impl.netty_http.client.NettyHttpClient;
+import com.xxl.rpc.serialize.impl.HessianSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author xuxueli 2018-10-28 00:18:17
+ */
+
+public class XxlJobScheduler {
+ private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class);
+
+
+ public void init() throws Exception {
+ // init i18n
+ initI18n();
+
+ // admin registry monitor run
+ JobRegistryMonitorHelper.getInstance().start();
+
+ // admin monitor run
+ JobFailMonitorHelper.getInstance().start();
+
+ // admin trigger pool start
+ JobTriggerPoolHelper.toStart();
+
+ // start-schedule
+ JobScheduleHelper.getInstance().start();
+
+ logger.info(">>>>>>>>> init xxl-job admin success.");
+ }
+
+
+ public void destroy() throws Exception {
+
+ // stop-schedule
+ JobScheduleHelper.getInstance().toStop();
+
+ // admin trigger pool stop
+ JobTriggerPoolHelper.toStop();
+
+ // admin monitor stop
+ JobFailMonitorHelper.getInstance().toStop();
+
+ // admin registry stop
+ JobRegistryMonitorHelper.getInstance().toStop();
+
+ }
+
+ // ---------------------- I18n ----------------------
+
+ private void initI18n(){
+ for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
+ item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
+ }
+ }
+
+ // ---------------------- executor-client ----------------------
+ private static ConcurrentMap executorBizRepository = new ConcurrentHashMap();
+ public static ExecutorBiz getExecutorBiz(String address) throws Exception {
+ // valid
+ if (address==null || address.trim().length()==0) {
+ return null;
+ }
+
+ // load-cache
+ address = address.trim();
+ ExecutorBiz executorBiz = executorBizRepository.get(address);
+ if (executorBiz != null) {
+ return executorBiz;
+ }
+
+ // set-cache
+ XxlRpcReferenceBean referenceBean = new XxlRpcReferenceBean();
+ referenceBean.setClient(NettyHttpClient.class);
+ referenceBean.setSerializer(HessianSerializer.class);
+ referenceBean.setCallType(CallType.SYNC);
+ referenceBean.setLoadBalance(LoadBalance.ROUND);
+ referenceBean.setIface(ExecutorBiz.class);
+ referenceBean.setVersion(null);
+ referenceBean.setTimeout(3000);
+ referenceBean.setAddress(address);
+ referenceBean.setAccessToken(XxlJobAdminConfig.getAdminConfig().getAccessToken());
+ referenceBean.setInvokeCallback(null);
+ referenceBean.setInvokerFactory(null);
+
+ executorBiz = (ExecutorBiz) referenceBean.getObject();
+
+ executorBizRepository.put(address, executorBiz);
+ return executorBiz;
+ }
+
+}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryMonitorHelper.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryMonitorHelper.java
index 6c838e04..1e91014f 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryMonitorHelper.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryMonitorHelper.java
@@ -7,10 +7,7 @@ import com.xxl.job.core.enums.RegistryConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@@ -38,14 +35,14 @@ public class JobRegistryMonitorHelper {
if (groupList!=null && !groupList.isEmpty()) {
// remove dead address (admin/executor)
- List ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT);
+ List ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids!=null && ids.size()>0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// fresh online address (admin/executor)
HashMap> appAddressMap = new HashMap>();
- List list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT);
+ List list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item: list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java
index 404851f1..8d212cc2 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java
@@ -50,6 +50,9 @@ public class JobScheduleHelper {
}
logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
+ // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
+ int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20;
+
while (!scheduleThreadToStop) {
// Scan Job
@@ -73,7 +76,7 @@ public class JobScheduleHelper {
// 1、pre read
long nowTime = System.currentTimeMillis();
- List scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS);
+ List scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
if (scheduleList!=null && scheduleList.size()>0) {
// 2、push time-ring
for (XxlJobInfo jobInfo: scheduleList) {
@@ -88,20 +91,15 @@ public class JobScheduleHelper {
} else if (nowTime > jobInfo.getTriggerNextTime()) {
// 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
- CronExpression cronExpression = new CronExpression(jobInfo.getJobCron());
- long nextTime = cronExpression.getNextValidTimeAfter(new Date()).getTime();
-
// 1、trigger
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );
// 2、fresh next
- jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
- jobInfo.setTriggerNextTime(nextTime);
-
+ refreshNextValidTime(jobInfo, new Date());
// next-trigger-time in 5s, pre-read again
- if (jobInfo.getTriggerNextTime() - nowTime < PRE_READ_MS) {
+ if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {
// 1、make ring second
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java
index f4375346..d4d4db94 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java
@@ -1,5 +1,6 @@
package com.xxl.job.admin.core.thread;
+import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
import org.slf4j.Logger;
@@ -20,31 +21,44 @@ public class JobTriggerPoolHelper {
// ---------------------- trigger pool ----------------------
// fast/slow thread pool
- private ThreadPoolExecutor fastTriggerPool = new ThreadPoolExecutor(
- 50,
- 200,
- 60L,
- TimeUnit.SECONDS,
- new LinkedBlockingQueue(1000),
- new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
- }
- });
-
- private ThreadPoolExecutor slowTriggerPool = new ThreadPoolExecutor(
- 10,
- 100,
- 60L,
- TimeUnit.SECONDS,
- new LinkedBlockingQueue(2000),
- new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
- }
- });
+ private ThreadPoolExecutor fastTriggerPool = null;
+ private ThreadPoolExecutor slowTriggerPool = null;
+
+ public void start(){
+ fastTriggerPool = new ThreadPoolExecutor(
+ 10,
+ XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
+ 60L,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue(1000),
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
+ }
+ });
+
+ slowTriggerPool = new ThreadPoolExecutor(
+ 10,
+ XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
+ 60L,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue(2000),
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
+ }
+ });
+ }
+
+
+ public void stop() {
+ //triggerPool.shutdown();
+ fastTriggerPool.shutdownNow();
+ slowTriggerPool.shutdownNow();
+ logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success.");
+ }
// job timeout count
@@ -100,17 +114,19 @@ public class JobTriggerPoolHelper {
});
}
- public void stop() {
- //triggerPool.shutdown();
- fastTriggerPool.shutdownNow();
- slowTriggerPool.shutdownNow();
- logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success.");
- }
+
// ---------------------- helper ----------------------
private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper();
+ public static void toStart() {
+ helper.start();
+ }
+ public static void toStop() {
+ helper.stop();
+ }
+
/**
* @param jobId
* @param triggerType
@@ -126,8 +142,4 @@ public class JobTriggerPoolHelper {
helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
}
- public static void toStop() {
- helper.stop();
- }
-
}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java
index 7b3971c7..d2a92b8a 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java
@@ -1,7 +1,7 @@
package com.xxl.job.admin.core.trigger;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
-import com.xxl.job.admin.core.conf.XxlJobScheduler;
+import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
@@ -116,7 +116,7 @@ public class XxlJobTrigger {
triggerParam.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
triggerParam.setExecutorTimeout(jobInfo.getExecutorTimeout());
triggerParam.setLogId(jobLog.getId());
- triggerParam.setLogDateTim(jobLog.getTriggerTime().getTime());
+ triggerParam.setLogDateTime(jobLog.getTriggerTime().getTime());
triggerParam.setGlueType(jobInfo.getGlueType());
triggerParam.setGlueSource(jobInfo.getGlueSource());
triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java
index 6dcb35b0..d640efff 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java
@@ -41,7 +41,7 @@ public interface XxlJobInfoDao {
public int findAllCount();
- public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime);
+ public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize );
public int scheduleUpdate(XxlJobInfo xxlJobInfo);
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java
index 10706003..1005c46c 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java
@@ -4,6 +4,7 @@ import com.xxl.job.admin.core.model.XxlJobRegistry;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+import java.util.Date;
import java.util.List;
/**
@@ -12,19 +13,23 @@ import java.util.List;
@Mapper
public interface XxlJobRegistryDao {
- public List findDead(@Param("timeout") int timeout);
+ public List findDead(@Param("timeout") int timeout,
+ @Param("nowTime") Date nowTime);
public int removeDead(@Param("ids") List ids);
- public List findAll(@Param("timeout") int timeout);
+ public List findAll(@Param("timeout") int timeout,
+ @Param("nowTime") Date nowTime);
public int registryUpdate(@Param("registryGroup") String registryGroup,
@Param("registryKey") String registryKey,
- @Param("registryValue") String registryValue);
+ @Param("registryValue") String registryValue,
+ @Param("updateTime") Date updateTime);
public int registrySave(@Param("registryGroup") String registryGroup,
@Param("registryKey") String registryKey,
- @Param("registryValue") String registryValue);
+ @Param("registryValue") String registryValue,
+ @Param("updateTime") Date updateTime);
public int registryDelete(@Param("registryGroup") String registryGroup,
@Param("registryKey") String registryKey,
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java
index 92f5db26..88fd2674 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java
@@ -17,6 +17,7 @@ import com.xxl.job.core.handler.IJobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.text.MessageFormat;
@@ -126,9 +127,17 @@ public class AdminBizImpl implements AdminBiz {
@Override
public ReturnT registry(RegistryParam registryParam) {
- int ret = xxlJobRegistryDao.registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
+
+ // valid
+ if (!StringUtils.hasText(registryParam.getRegistGroup())
+ || !StringUtils.hasText(registryParam.getRegistryKey())
+ || !StringUtils.hasText(registryParam.getRegistryValue())) {
+ return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument.");
+ }
+
+ int ret = xxlJobRegistryDao.registryUpdate(registryParam.getRegistGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
if (ret < 1) {
- xxlJobRegistryDao.registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
+ xxlJobRegistryDao.registrySave(registryParam.getRegistGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
// fresh
freshGroupRegistryInfo(registryParam);
@@ -138,7 +147,15 @@ public class AdminBizImpl implements AdminBiz {
@Override
public ReturnT registryRemove(RegistryParam registryParam) {
- int ret = xxlJobRegistryDao.registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
+
+ // valid
+ if (!StringUtils.hasText(registryParam.getRegistGroup())
+ || !StringUtils.hasText(registryParam.getRegistryKey())
+ || !StringUtils.hasText(registryParam.getRegistryValue())) {
+ return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument.");
+ }
+
+ int ret = xxlJobRegistryDao.registryDelete(registryParam.getRegistGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
if (ret > 0) {
// fresh
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
index 9bbbf3ac..6c808d16 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
@@ -117,6 +117,9 @@ public class XxlJobServiceImpl implements XxlJobService {
}
// add in db
+ jobInfo.setAddTime(new Date());
+ jobInfo.setUpdateTime(new Date());
+ jobInfo.setGlueUpdatetime(new Date());
xxlJobInfoDao.save(jobInfo);
if (jobInfo.getId() < 1) {
return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
@@ -220,6 +223,8 @@ public class XxlJobServiceImpl implements XxlJobService {
exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount());
exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
exists_jobInfo.setTriggerNextTime(nextTriggerTime);
+
+ exists_jobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(exists_jobInfo);
@@ -260,6 +265,7 @@ public class XxlJobServiceImpl implements XxlJobService {
xxlJobInfo.setTriggerLastTime(0);
xxlJobInfo.setTriggerNextTime(nextTriggerTime);
+ xxlJobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(xxlJobInfo);
return ReturnT.SUCCESS;
}
@@ -272,6 +278,7 @@ public class XxlJobServiceImpl implements XxlJobService {
xxlJobInfo.setTriggerLastTime(0);
xxlJobInfo.setTriggerNextTime(0);
+ xxlJobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(xxlJobInfo);
return ReturnT.SUCCESS;
}
diff --git a/xxl-job-admin/src/main/resources/application.properties b/xxl-job-admin/src/main/resources/application.properties
index 8cf1f235..36ac06ec 100644
--- a/xxl-job-admin/src/main/resources/application.properties
+++ b/xxl-job-admin/src/main/resources/application.properties
@@ -44,3 +44,7 @@ xxl.job.accessToken=
### xxl-job, i18n (default empty as chinese, "en" as english)
xxl.job.i18n=
+
+## xxl-job, triggerpool max size
+xxl.job.triggerpool.fast.max=200
+xxl.job.triggerpool.slow.max=100
diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
index 0407011a..cb9048d2 100644
--- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
+++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
@@ -133,8 +133,8 @@
#{jobGroup},
#{jobCron},
#{jobDesc},
- NOW(),
- NOW(),
+ #{addTime},
+ #{updateTime},
#{author},
#{alarmEmail},
#{executorRouteStrategy},
@@ -146,7 +146,7 @@
#{glueType},
#{glueSource},
#{glueRemark},
- NOW(),
+ #{glueUpdatetime},
#{childJobId},
#{triggerStatus},
#{triggerLastTime},
@@ -170,7 +170,7 @@
job_group = #{jobGroup},
job_cron = #{jobCron},
job_desc = #{jobDesc},
- update_time = NOW(),
+ update_time = #{updateTime},
author = #{author},
alarm_email = #{alarmEmail},
executor_route_strategy = #{executorRouteStrategy},
@@ -212,7 +212,9 @@
SELECT
FROM xxl_job_info AS t
WHERE t.trigger_status = 1
- and t.trigger_next_time #{maxNextTime}
+ and t.trigger_next_time #{maxNextTime}
+ ORDER BY id ASC
+ LIMIT #{pagesize}
diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml
index 6a390ffb..2dd1a96a 100644
--- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml
+++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml
@@ -36,8 +36,8 @@
#{glueType},
#{glueSource},
#{glueRemark},
- now(),
- now()
+ #{addTime},
+ #{updateTime}
);