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} );