diff --git a/README.md b/README.md index 2b9a561ff74dba3f9c94cd6a9587f3ee738d43a3..db1aea01db87d476cdf47c283a822d21184255ea 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是 - 20、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python等类型脚本; - 21、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度; - 22、失败处理策略;调度失败时的处理策略,策略包括:失败告警(默认)、失败重试; +- 23、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时传递分片参数;可根据分片参数开发分片任务; ### 架构图 diff --git "a/doc/XXL-JOB\345\256\230\346\226\271\346\226\207\346\241\243.md" "b/doc/XXL-JOB\345\256\230\346\226\271\346\226\207\346\241\243.md" index ddde89ee54a4df2d2934cab31919a0cac1dec39b..fb6dc63f8b0f3d06dd5994d6e4baa19a5e9337b9 100644 --- "a/doc/XXL-JOB\345\256\230\346\226\271\346\226\207\346\241\243.md" +++ "b/doc/XXL-JOB\345\256\230\346\226\271\346\226\207\346\241\243.md" @@ -34,6 +34,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是 - 20、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python等类型脚本; - 21、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度; - 22、失败处理策略;调度失败时的处理策略,策略包括:失败告警(默认)、失败重试; +- 23、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务; ### 1.3 发展 于2015年中,我在github上创建XXL-JOB项目仓库并提交第一个commit,随之进行系统结构设计,UI选型,交互设计…… @@ -272,7 +273,7 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是 - 执行器:任务的绑定的执行器,任务触发调度时将会自动发现注册成功的执行器, 实现任务自动发现功能; 另一方面也可以方便的进行任务分组。每个任务必须绑定一个执行器, 可在 "执行器管理" 进行设置; - 描述:任务的描述信息,便于任务管理; - - 路由策略:当执行器集群部署时,执行器路由规则; + - 路由策略:当执行器集群部署时,提供丰富的路由策略,包括; FIRST(第一个):固定选择第一个执行器; LAST(最后一个):固定选择最后一个执行器; ROUND(轮询):; @@ -282,6 +283,8 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是 LEAST_RECENTLY_USED(最近最久未使用):单个JOB对应的每个执行器,最久为使用的优先被选举; FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度; BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度; + SHARDING_BROADCAST(分片广播):广播触发对应集群中所有执行器执行一次任务,同时传递分片参数;可根据分片参数开发分片任务; + - Cron:触发任务执行的Cron表达式; - 运行模式: BEAN模式:任务以JobHandler方式维护在执行器端;需要结合 "JobHandler" 属性匹配执行器中任务; @@ -679,24 +682,29 @@ XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 为保证系统"轻量级"并且降低学习部署成本,没有采用Zookeeper作为注册中心,采用DB方式进行任务注册发现; -#### 5.8 路由策略 -执行器集群部署时提供丰富的路由策略,包括: - - FIRST(第一个):固定选择第一个执行器; - LAST(最后一个):固定选择最后一个执行器; - ROUND(轮询):; - RANDOM(随机):随机选择在线的执行器; - CONSISTENT_HASH(一致性HASH):分组下机器地址相同,不同JOB均匀散列在不同机器上,保证分组下机器分配JOB平均;且每个JOB固定调度其中一台机器; - LEAST_FREQUENTLY_USED(最不经常使用):单个JOB对应的每个执行器,使用频率最低的优先被选举; - LEAST_RECENTLY_USED(最近最久未使用):单个JOB对应的每个执行器,最久为使用的优先被选举; - FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度; - BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度; - -#### 5.9 任务执行结果 +#### 5.8 任务执行结果 自v1.6.2之后,任务执行结果通过 "IJobHandler" 的返回值 "ReturnT" 进行判断; 当返回值符合 "ReturnT.code == ReturnT.SUCCESS_CODE" 时表示任务执行成功,否则表示任务执行失败,而且可以通过 "ReturnT.msg" 回调错误信息给调度中心; 从而,在任务逻辑中可以方便的控制任务执行结果; +#### 5.9 "分片广播" 特性 +执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时传递分片参数;可根据分片参数开发分片任务; + +"分片广播" 是以执行器集群进行分片,每个执行器属于一片,激情中多个执行器可协同分片处理大数据量任务; + +"分片广播" 和普通任务开发流程一致,不同之处在于可以可以获取分片参数,获取分片参数对象的代码如下(可参考example执行器中的示例任务"ShardingJobHandler" ): + + ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo(); + +该分片参数对象拥有两个属性: + + index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号; + total:总分片数,执行器集群的总机器数量; + +该特性适用场景如: +- 1、分片任务场景:10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍; +- 2、广播任务场景:广播执行器机器运行shell脚本、广播集群节点进行缓存更新等 + ## 六、版本更新日志 #### 6.1 版本 V1.1.x,新特性[2015-12-05] @@ -888,7 +896,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段 - 11、调度中心任务注册检测逻辑优化; #### 6.18 版本 V1.8.1 特性[快照版本] -- 1、任务分片:一个任务被拆分成N个独立的任务单元,然后由分布式部署的执行器分别执行某一个或几个分片单元; +- 1、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数处理分片任务; - 2、执行器JobHandler禁止命名冲突; #### TODO LIST diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java index 626af4e7f77a5fbd67ea74ab8fa42d850a554f73..9e82ef56859326277afa8859b035a09154426dc7 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java @@ -16,7 +16,7 @@ public enum ExecutorRouteStrategyEnum { LEAST_RECENTLY_USED("最近最久未使用", new ExecutorRouteLRU()), FAILOVER("故障转移", new ExecutorRouteFailover()), BUSYOVER("忙碌转移", new ExecutorRouteBusyover()), - BROADCAST("广播", null); + SHARDING_BROADCAST("分片广播", null); ExecutorRouteStrategyEnum(String title, ExecutorRouter router) { this.title = title; 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 aeacddfa7c24853cfdd69e98d79bea0d4294344b..bbad8c1e1c5da4af1d0b757f870109238dffc0ff 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 @@ -42,7 +42,7 @@ public class XxlJobTrigger { ArrayList addressList = (ArrayList) group.getRegistryList(); // broadcast - if (ExecutorRouteStrategyEnum.BROADCAST == executorRouteStrategyEnum && CollectionUtils.isNotEmpty(addressList)) { + if (ExecutorRouteStrategyEnum.SHARDING_BROADCAST == executorRouteStrategyEnum && CollectionUtils.isNotEmpty(addressList)) { for (int i = 0; i < addressList.size(); i++) { String address = addressList.get(i); diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl index f5f48503d8ceac02dd7e04c232b9b5925482e4d8..dc73f6d4a06eadf727231a8f75628cc04350ea85 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl @@ -5,7 +5,7 @@ <#import "/common/common.macro.ftl" as netCommon> <@netCommon.commonStyle /> -sidebar-collapse "> +sidebar-collapse ">
<@netCommon.commonHeader /> diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl index 2809c09f980b58043f1041b03d4bab55e4abc8cb..347d89779c925d7c9821efc7c0fd3025b302f6b2 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl @@ -5,7 +5,7 @@ <#import "/common/common.macro.ftl" as netCommon> <@netCommon.commonStyle /> -sidebar-collapse "> +sidebar-collapse ">
<@netCommon.commonHeader /> diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobgroup/jobgroup.index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobgroup/jobgroup.index.ftl index 4bd8f44d2dfa2897703d7290941cf26331f6d11c..5819d83fe66cb2f7863de4b7fd1f8a12ddb34e58 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobgroup/jobgroup.index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobgroup/jobgroup.index.ftl @@ -7,7 +7,7 @@ -sidebar-collapse "> +sidebar-collapse ">
<@netCommon.commonHeader /> diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl index e512b1745ffae3c21fb6ef994c7672f120a8680d..1389ae4bb2dba3dfc4f590101b0f399e4f2ea7ea 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl @@ -8,7 +8,7 @@ -sidebar-collapse"> +sidebar-collapse">
<@netCommon.commonHeader /> diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl index f653e7a852c2bea333c94aab9bb706f30ffd556d..197722dcf6a1d45993cf039f3b23865aca571586 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl @@ -9,7 +9,7 @@ -sidebar-collapse "> +sidebar-collapse ">
<@netCommon.commonHeader /> diff --git a/xxl-job-admin/src/main/webapp/static/js/common.1.js b/xxl-job-admin/src/main/webapp/static/js/common.1.js index bd879436228cbfd2059b67ef59b6ec565ea0fe04..515325f5daca828e9bfb18cefb77a2132d6c3820 100644 --- a/xxl-job-admin/src/main/webapp/static/js/common.1.js +++ b/xxl-job-admin/src/main/webapp/static/js/common.1.js @@ -71,18 +71,18 @@ $(function(){ // 左侧菜单状态,js + 后端 + cookie方式(新) $('.sidebar-toggle').click(function(){ - var adminlte_settings = $.cookie('adminlte_settings'); // 左侧菜单展开状态[adminlte_settings]:on=展开,off=折叠 - if ('off' == adminlte_settings) { - adminlte_settings = 'on'; + var xxljob_adminlte_settings = $.cookie('xxljob_adminlte_settings'); // 左侧菜单展开状态[xxljob_adminlte_settings]:on=展开,off=折叠 + if ('off' == xxljob_adminlte_settings) { + xxljob_adminlte_settings = 'on'; } else { - adminlte_settings = 'off'; + xxljob_adminlte_settings = 'off'; } - $.cookie('adminlte_settings', adminlte_settings, { expires: 7 }); //$.cookie('the_cookie', '', { expires: -1 }); + $.cookie('xxljob_adminlte_settings', xxljob_adminlte_settings, { expires: 7 }); //$.cookie('the_cookie', '', { expires: -1 }); }); // 左侧菜单状态,js + cookie方式(遗弃) /* - var adminlte_settings = $.cookie('adminlte_settings'); - if (adminlte_settings == 'off') { + var xxljob_adminlte_settings = $.cookie('xxljob_adminlte_settings'); + if (xxljob_adminlte_settings == 'off') { $('body').addClass('sidebar-collapse'); } */ diff --git a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java index 8f2b15e449363a88d5fdb9f902d792e0dd280293..66560353a457fceb0e3a0a45940e2032519e0f7d 100644 --- a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java +++ b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Service; /** - * 广播分片任务 + * 分片广播任务 * * @author xuxueli 2017-07-25 20:56:50 */ diff --git a/xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java b/xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java index 91166eb2ef46d2c7f3a2fd8a4daedeba5e9ff4f2..c8b15602c61928783cb8a0389683ee9544bdc93d 100644 --- a/xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java +++ b/xxl-job-executor-springboot-example/src/main/java/com/xxl/job/executor/service/jobhandler/ShardingJobHandler.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Service; /** - * 广播分片任务 + * 分片广播任务 * * @author xuxueli 2017-07-25 20:56:50 */