XXL-JOB任务分片

news/2024/5/19 1:36:58 标签: java, 开发语言, xxl-job

文章目录

    • 任务类型
    • 任务配置
      • 路由策略
      • 阻塞处理策略:
    • 单个任务和集群任务
    • 单机多任务分片
    • 集群分片

任务类型

  • 单个任务:一个任务实例便可完成

    • 单机单任务:单机模式下任何路由模式都只有一个实例执行

    • 集群单任务:由路由策略(广播模式除外)选择其中一个实例完成

  • 分片任务:集群部署,每个实例都同时执行一部分数据。分片方式:取模分片,范围分片

    • 单机多任务分片:单机模式下,创建同类型任务多个任务计划,手工分片数据作为参数

    • 集群任务分片:只有广播模式会通知所有实例都会运行,每个节点取模执行任务

任务配置

路由策略

策略参数值详细含义
第一个FIRST固定选择第一个机器
最后一个LAST固定选择最后一个机器
轮询ROUND依次选择执行
随机RANDOM随机选择在线的机器
一致性HASHCONSISTENT_HASH每个人物按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上
最不经常使用LEAST_FREQUENTLY_USED使用频率最低的机器优先被选择
最近最久未使用LEAST_RECENTLY_USED最久未使用的机器优先被选择
故障转义FAILOVER按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度
忙碌转义BUSYOVER按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定位目标执行器并发起调度
分片广播SHARDING_BROADCAST广播触发对应集群中所有机器执行一次任务,同事系统自动传递分片参数,可根据分片参数开发分片任务

子任务ID:

当有任务需要相互依赖时使用,比如在对账业务里,下载对账文件任务成功之后,才开始对账。那么,可以把这几个任务当成一个大任务来串行处理,即在一个任务的末尾触发另一个任务。

如果我们需要在本任务执行结束并且执行成功的时候触发另外一个任务,那么就可以把另外的任务作为本任务的子任务运行,就只需要在本任务里填入另外一个任务的jobId即可(可以在任务列表查看JobId)

阻塞处理策略:

策略参数值含义
单机串行,默认SERIAL_EXECUTION调度请求进入单机执行器后,调度请求进入FIFO
丢弃后续调度DISCARD_LATER调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败
覆盖之前调度COVER_EARLY调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本次调度任务

单个任务和集群任务

java">@Component
public class SimpleJobHandler {

    @XxlJob(value ="simpleJobHandler" )
    public ReturnT<String> execute(String param) throws InterruptedException {

        IntStream.rangeClosed(1,20).forEach(index->{
            XxlJobLogger.log("simpleJobHandler>>"+index);
        });
        //官方文档说 如果任务超时 是采用interrupt机制打断子线程的,因此需要将InterruptedException 向上抛出
        //不能catch,否则任务超时后 任务还会被正常执行完
        Thread.sleep(ThreadLocalRandom.current().nextInt(10000));

        //任务超时后 这句日志不会被打印出来:xxl-job任务需用XxlJobLogger输出日志
        XxlJobLogger.log("执行完毕");

        return ReturnT.SUCCESS;
    }

}

xxl-job任务需用XxlJobLogger输出日志

单机模式:只启动一个任务执行器实例,修改路由模式即便是广播模式依然只有一个实例运行job

集群模式:启动多个任务实例,这里可以把每个实例的端口号都改为不同,可以看到同一个任务类有多个机器。除了广播模式,其他模式都只会选择机器列表中的一个执行job

单机多任务分片

对于多10条数据,我们可以创建多个任务每个任务完成不同的ID数据,只要ID不重合,那么就不会重复执行对应的事务

这里我们按id划分,[1,3,5,7,9],[2,4,6,8,10]为两组

java">    @XxlJob(value = "singleMachineMultiTasks", init = "init", destroy = "destroy")
    public ReturnT<String> singleMachineMultiTasks(String cities) throws Exception {

        if (StringUtils.isEmpty(cities)) {
            return new ReturnT(FAIL_CODE, "latnIds不能为空");
        }
         XxlJobLogger.log("任务参数={}", cities);
        //str转int数组,遍历ID列表
        Arrays.stream(cities.split(",")).map(String::trim).filter(StringUtils::isNotBlank).map(Integer::parseInt).forEach(latnId -> {
            //获取对应ID的未处理数据集合,遍历未处理数据集合并执行对应业务
            List<String> tasks = singleMachineMultiTasks.get(latnId);
            Optional.ofNullable(tasks).ifPresent(todoTasks -> {
                todoTasks.forEach(task -> {
                    XxlJobLogger.log("【{}】执行【{}】,任务内容为:{}", Thread.currentThread().getName(), latnId, task);
                });
            });
        });
        return ReturnT.SUCCESS;
    }


分别启动两个任务,并在管理器上配置好对应的参数
在这里插入图片描述
查看执行日志,两个控制台分别打印对应的执行日志如下:

java">任务参数=1,3,5,7,91】执行【{Thread-1}】,任务内容为:{武汉}3】执行【{Thread-1}】,任务内容为:{北京}5】执行【{Thread-1}】,任务内容为:{上海}



任务参数=2,4,6,8,102】执行【{Thread-20}】,任务内容为:{222}4】执行【{Thread-20}】,任务内容为:{444}6】执行【{Thread-20}】,任务内容为:{666}

集群分片

采用多机器取模的方式,来为不同的机器指定各自服务的ID列表

java"> @XxlJob(value = "multiMachineMultiTasks", init = "init", destroy = "destroy")
    public ReturnT<String> multiMachineMultiTasks(String params) throws Exception {
        ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
        int n = shardingVO.getTotal(); // 动态获取所有实例数  
        int i = shardingVO.getIndex(); // 当前为第i个序号

        IntStream.range(0, CITY_ID_LIST.size()).forEach(cityIndex -> {
             //使用取余分片
            if (cityIndex % n == i) {
                int city = CITY_ID_LIST.get(cityIndex);
                List<String> tasks = singleMachineMultiTasks.get(city);
                Optional.ofNullable(tasks).ifPresent(todoTasks -> {
                    todoTasks.forEach(task -> {
                        XxlJobLogger.log("实例【{}】执行【{}】,任务内容为:{}", i, city, task);
                    });

                });
            }
        });
        return ReturnT.SUCCESS;
    }


 
    public void init() {
     log.info("init");
 }

 public void destroy() {
     log.info("destory");
 }

如果不显示的指明生命周期函数,在方法执行完之后,会被销毁。

新增一个任务,路由策略为分片广播
在这里插入图片描述
启动多个执行器实例
在这里插入图片描述
可以看到这个任务执执行器的机器地址有多个实例,说明它是集群模式运行。

查看控制台每个实例的日志都会根据取余分片执行不同的ID和任务内容
在这里插入图片描述
如果两个停一个,分片总数会发生变化,并且当前分片数也可能会发生变化

提出问题:取模方式对于顺序ID(自增ID)能很好的均匀分派分片数,那么对于范围分片(时间段分片)显然这里是没有提供类似分片算法的,根据实际项目情况,不一定非要用分片算法,不过不用分片算法,那么单例job又和没用有何区别呢?


http://www.niftyadmin.cn/n/414767.html

相关文章

一路狂飙,性能测试流程与性能测试主要指标整理,直接上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试实战 性…

Revit中绘制弯曲的靠背栏杆和生成过梁

一、Revit中怎么绘制弯曲的靠背栏杆 栏杆通常我们见过位于在阳台处&#xff0c;但是在我们的古建筑中很常见到一种靠背栏杆&#xff0c;例如凉亭里面就很常见这种栏杆。那么如何绘制呢? 利用公制栏杆——支柱进行绘制 要运用放样工具进行绘制&#xff0c;设置一个工作平面&…

让你的AndroidUI更亮眼:Jetpack Compose中的可视状态

让你的Android UI更亮眼&#xff1a;Jetpack Compose中的可视状态 任何设计系统的重要责任是清晰地表明哪些组件可以与之交互&#xff0c;哪些不行&#xff0c;并让用户知道交互已发生。本博客文章将解释如何监听Jetpack Compose中的用户交互&#xff0c;并创建可重用的视觉指…

PyCaret解决二分类任务教程示例

PyCaret是一个Python中的开源、低代码机器学习库&#xff0c;可以自动化机器学习工作流。它是一个端到端的机器学习和模型管理工具&#xff0c;可以成倍地加快实验周期&#xff0c;提高工作效率。 与其他开源机器学习库相比&#xff0c;PyCaret是一个替代的低代码库&#xff0c…

【漏洞修复】node-exporter被检测出来pprof调试信息泄露漏洞

node-exporter被检测出来pprof调试信息泄露漏洞 说在前面解决方法结语 说在前面 惯例开篇吐槽&#xff0c;有些二五仔习惯搞点自研的安全扫描工具&#xff0c;然后加点DIY元素&#xff0c;他也不管扫的准不准&#xff0c;就要给你报个高中危的漏洞&#xff0c;然后就要去修复&…

07.JavaWeb-Vue+elementUI

1.Vue 功能替代JavaScript和jQuery&#xff0c;基于JavaScript实现的前端框架 1.1配置Vue 1.1.1引入vue库 方法一&#xff1a;通过cdn链接引入最新版本的vue&#xff08;可能会慢些&#xff09; <head><script src"https://cdn.jsdelivr.net/npm/vue">…

word如何转化为pdf格式?分享四个方法给大家!

在工作和学习中&#xff0c;经常需要对文档进行转换&#xff0c;其中将Word文档转换为PDF是最常见的格式转换之一。下面介绍几种常用的转换方法&#xff0c;包括使用记灵在线工具。 方法一&#xff1a;使用Word软件直接转换 如果你使用的是电脑上的Word软件&#xff0c;可以直…

TCP连接管理与UDP协议

一、TCP的连接管理 1.TCP包头 2.连接的建立——“三次握手” TCP 建立连接的过程叫做握手。 采用三报文握手&#xff1a;在客户和服务器之间交换三个 TCP 报文段&#xff0c;以防止已失效的连接请求报文段突然又传送到了&#xff0c;因而产生 TCP 连接建立错误。 3.连接的释放…