10分钟快速体验

通过将应用镜像上传到阿里云的容器服务平台,并接入任务调度平台,可以有效地进行定时任务调度和任务分片,实现高效的任务管理和调度。

视频演示

如需快速接入并体验XXL-JOB,请参见10分钟快速体验XXL-JOB视频演示

前提条件

方案概览

本方案以产品提供的业务应用Demo镜像为例,通过ACK Serverless和SAE两种部署方式,将Demo镜像部署到容器,然后接入到分布式任务调度平台XXL-JOB,进行单机和分片广播的定时任务测试,帮助您全面了解和掌握XXL-JOB的使用与配置。大致分为以下几步:

  1. 创建应用:在XXL-JOB平台创建应用,方便对任务集群化查看、配置和调度,提升管理效率。

  2. 部署Demo工程到容器:将业务镜像通过ACK Serverless和SAE两种部署方式,实现业务镜像快速部署和扩展的能力。

  3. 测试验证:确保已接入的应用能够在XXLJOB平台上正常自动化调度和管理,任务能够按计划准时准确执行。

步骤一:创建应用

  1. 登录XXL-JOB控制台,并在顶部菜单栏选择地域。

  2. 单击目标实例,进入实例详情页,在左侧导航栏,选择应用管理,单击创建应用。填写AppName名称,使用系统自动生成的AccessToken,单击确定

步骤二:部署Demo工程到容器

产品提供了公共的业务应用Demo镜像:registry.cn-hangzhou.aliyuncs.com/schedulerx/xxljob-demo:2.2.0。可通过以下两种方式,选择其一部署Demo应用接入XXLJOB实例测试体验。

重要

确保任务部署集群和XXLJOB集群在同一VPC中,且应用节点所在的安全组入方向配置允许 VPC 网段的访问。

通过ACK Serverless部署

  1. 创建容器服务集群。登录阿里云容器服务控制台,创建一个ACK Serverless集群。需为当前VPC开启配置“SNAT”(VPC已配置过则可忽略),以便拉取Demo镜像。

    image

  2. 在左侧导航栏的应用管理页面,单击目标应用操作列的接入配置

  3. 在容器服务控制台的集群列表页,单击目标集群,选择工作负载 > 无状态服务,点击使用YAML创建资源,本文以接入方式2(通过-D参数重启应用)为例进行接入配置,替换YAML的JAVA_OPTS列中,将YAML配置填充启动。

    image

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: xxljob-demo
      labels:
        app: xxljob-demo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: xxljob-demo
      template:
        metadata:
          labels:
            app: xxljob-demo
        spec:
          containers:
          - name: xxljob-executor
            image: registry.cn-hangzhou.aliyuncs.com/schedulerx/xxljob-demo:2.2.0
            ports:
            - containerPort: 9999
            env:
              - name: JAVA_OPTS
                value: >-
                  -Dxxl.job.admin.addresses=http://xxljob-xxxxx.schedulerx.mse.aliyuncs.com
                  -Dxxl.job.executor.appname=xxxxx
                  -Dxxl.job.accessToken=xxxxxxx

通过SAE部署

  1. 创建Serverless应用集群。登录阿里云Serverless应用引擎SAE,进入应用管理 > 微服务应用,单击创建应用,创建一个微服务应用。

  2. 创建应用并配置应用基本信息。选择已有命名空间,选择对应VPC下的交换机/安全组。点击设置镜像,切换到自定义镜像,输入Demo镜像地址:registry.cn-hangzhou.aliyuncs.com/schedulerx/xxljob-demo:2.2.0后,单击下一步。

    重要

    对应命名空间需要绑定XXLJOB实例集群所在的VPC。

    image

3. 进行高级设置,配置JAVA_OPS环境变量。

image

环境变量值参数获取如下:

登录XXL-JOB控制台,并在顶部菜单栏选择地域。单击目标实例,进入实例详情页。在左侧导航栏的应用管理页面,单击目标应用操作列的接入配置。本文以接入方式2为例,配置JAVA_OPS环境变量。

image

4. 单击创建应用,等待应用实例创建完成。

步骤三:测试验证

1.执行器接入验证

进入目标实例详情页,单击左侧导航栏的应用管理,在应用列表页面,单击目标应用的执行器数量,可看到接入的执行器地址和在线状态。

image

2.任务测试验证

官方提供的Demo镜像中包含测试Job代码,以供快速测试验证,其中包含如下jobHandler

  • 单机任务JobHandlerhelloworld

  • 分片广播任务JobHandlershardingJobHandler

参考代码内容如下

@Component
public class SampleXxlJob {
    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);

    @XxlJob("helloworld")
    public ReturnT<String> helloworld(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World, param=" + param);
        for (int i = 0; i < 5; i++) {
            XxlJobLogger.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        System.out.println("XXL-JOB, Hello World, finished");
        return ReturnT.SUCCESS;
    }


    /**
     * 1、简单任务示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        System.out.println("XXL-JOB, Hello World, start...");
        for (int i = 0; i < 5; i++) {
            System.out.println("beat at:" + i);
            XxlJobLogger.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        System.out.println("XXL-JOB, Hello World, end...");
        return ReturnT.SUCCESS;
    }


    /**
     * 2、分片广播任务
     */
    @XxlJob("shardingJobHandler")
    public ReturnT<String> shardingJobHandler(String param) throws Exception {

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

        // 业务逻辑
        for (int i = 0; i < shardingVO.getTotal(); i++) {
            if (i == shardingVO.getIndex()) {
                XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
            } else {
                XxlJobLogger.log("第 {} 片, 忽略", i);
            }
        }

        return ReturnT.SUCCESS;
    }


    /**
     * 3、命令行任务
     */
    @XxlJob("commandJobHandler")
    public ReturnT<String> commandJobHandler(String param) throws Exception {
        String command = param;
        int exitValue = -1;

        BufferedReader bufferedReader = null;
        try {
            // command process
            Process process = Runtime.getRuntime().exec(command);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
            bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));

            // command log
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                XxlJobLogger.log(line);
            }

            // command exit
            process.waitFor();
            exitValue = process.exitValue();
        } catch (Exception e) {
            XxlJobLogger.log(e);
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }

        if (exitValue == 0) {
            return IJobHandler.SUCCESS;
        } else {
            return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
        }
    }

    /**
     * 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
     */
    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public ReturnT<String> demoJobHandler2(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        return ReturnT.SUCCESS;
    }
    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destory");
    }
    
    @XxlJob(value = "failedJobHandler")
    public ReturnT<String> failedJobHandler(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        int a = 1/0;
        return ReturnT.SUCCESS;
    }

}

单机任务测试

单机任务表示每次执行在该应用下的所有执行器中按照路由策略选一台幂等执行。

  1. 在左侧导航栏,选择任务管理,单击创建任务。首先进行基本配置,填写任务名称jobHandler名称关联应用选择目标应用,路由策略选择轮询,然后单击下一步

    image

  2. 进行定时配置时间类型选择cron,通过单击使用生成工具按钮,生成cron表达式。本示例以每天12时执行一次为例,然后单击下一步

    image

  3. 进行通知配置,您可以在此配置超时报警、成功通知、失败报警、通知方式、通知对象。本示例以控制台默认配置为例。

    image

  4. 创建完成后,单击目标任务操作列中的运行一次,在手动执行任务弹框中,指定机器,配置实例参数,单击确定

    image

  5. 单击更多 > 调度记录,查看任务执行记录。

    image

  6. 单击左侧导航栏执行列表,单击目标执行记录操作列中的日志,查看本次任务的执行日志记录。

    image

分片广播任务测试

广播分片表示每次执行会广播该应用下所有执行器执行,每个执行器能拿到不同的分片号,可以用来做分布式批处理。开源XXLJOB分片广播无聚合功能,阿里云XXLJOB可以聚合展示每次执行的所有分片情况。

  1. 在左侧导航栏,选择任务管理,单击创建任务。首先进行基本配置,填写任务名称jobHandler名称关联应用选择目标应用,路由策略选择分片广播。然后单击下一步

    image

  2. 进行定时配置时间类型选择cron,通过单击使用生成工具按钮,生成cron表达式。本示例以每小时第10分执行一次为例,然后单击下一步

    image

  3. 进行通知配置,您可以在此配置设置超时报警、成功通知、失败报警、通知方式、通知对象。本示例以控制台默认配置为例。

    image

  4. 创建完成后,单击目标任务操作列中的运行一次,在手动执行任务弹框中,指定机器,配置实例参数,单击确定

    image

  5. 单击更多 > 调度记录,查看任务执行记录。

    image

  6. 单击左侧导航栏的执行列表,在任务执行列表页,单击目标任务执行操作列中的详情,在分片详情中可聚合展示每台机器的执行情况。

    image

  7. 针对每个分片,单击指定分片操作列中的日志,查看本次任务的执行日志记录。

    image