xxl-job简单任务和分片任务

简单任务

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

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

        return ReturnT.SUCCESS;
    }

}

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

在这里插入图片描述

其中页面上JobHandler对应于代码上@XxlJob的value值,超时时间设置2s

由于本地测试时 运行了多个执行器,所以路由策略那里选用了轮询。也可根据实际情况自行调整

查看下运行日志

在这里插入图片描述

发现当任务执行超时后,程序即被中断,后续的代码逻辑不再被执行。

分片任务

使用分片是为了更大效率地利用执行器集群资源,比如有一个任务需要处理20W条数据,每条数据的业务逻辑处理要0.1s。对于普通任务来说,只有一个线程来处理 可能需要5~6个小时才能处理完。

如果将20W数据均匀分给集群里的3台机器同时处理,那么耗时会大大缩短,也能充分利用集群资源。

在xxl-job里,如果有一个执行器集群有3个机器,那么分片总数是3,分片序号0,1,2 分别对应那三台机器。

举例:

有一个执行器集群,有三台机器。对一批用户信息进行处理,处理规则如下

  • id % 分片总数 余数是0 的,在第1个执行器上执行
  • id % 分片总数 余数是1 的,在第2个执行器上执行
  • id % 分片总数 余数是2 的,在第3个执行器上执行
@Component
public class ShardingJob {

    private List<User> userList;

    @PostConstruct
    public void init() {

        userList = LongStream.rangeClosed(1, 10)
                .mapToObj(index -> new User(index, "wojiushiwo" + index))
                .collect(Collectors.toList());

    }

    @XxlJob(value = "shardingJobHandler")
    public ReturnT<String> execute(String param) {

        //获取分片参数
        ShardingUtil.ShardingVO shardingVo = ShardingUtil.getShardingVo();
        XxlJobLogger.log("分片参数,当前分片序号={},总分片数={}", shardingVo.getIndex(), shardingVo.getTotal());

        for (int i = 0; i < userList.size(); i++) {
            //将数据均匀地分布到各分片上执行
            if (i % shardingVo.getTotal() == shardingVo.getIndex()) {
                XxlJobLogger.log("第 {} 片, 命中分片开始处理{}", shardingVo.getIndex(), userList.get(i).toString());
            } else {
                XxlJobLogger.log("{},忽略", shardingVo.getIndex());
            }

        }
        return ReturnT.SUCCESS;
    }


}

如果是数据库数据的话,可以进行如下处理,让每个分片执行一部分数据

-- 其中count是分片总数,index是当前分片数
select id,name
from user
where status=1 and mod(id,#{count})=#{index};

下面查看下三个执行器的执行日志:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值