快速入门

任务调度产品支持多种任务类型,包括简单任务、集群任务,您可以根据业务的需求,选择其一实现业务。本文以简单任务为例,介绍如何快速完成一个简单任务的本地开发以及控制台任务配置等。

说明

若您需要任务调度工程示例代码,请下载 示例工程

操作步骤

  1. 本地应用开发。

    1. 创建 SOFABoot 工程。

      下载并配置好一个 SOFABoot 工程原型。配置步骤,请参见 快速开始

      说明

      任务调度客户端支持使用 SOFABoot 框架或其它 Maven 工程框架开发。此处以 SOFABoot 为例介绍应用开发示例。非 SOFABoot 工程的配置,请参见 非 SOFABoot 工程。

    2. 引入任务调度的依赖。

      1. 在 SOFABoot 工程中引入任务调度的依赖:

        <dependency>
             <groupId>com.alipay.sofa</groupId>
             <artifactId>scheduler-enterprise-sofa-boot-starter</artifactId>
        </dependency>
      2. 对于 SOFABoot 3.4.3 以下的版本,需要添加如下 Tracer 依赖。

        说明

        • 添加前,请仔细检查工程是否已经依赖了 Tracer,避免 JAR 包冲突问题。

        • SOFABoot 已在 3.4.3 及其以上版本自动依赖 Tracer,无需再手动添加。SOFABoot 最新版本信息,详见 SOFABoot 版本说明

        <dependency>
             <groupId>com.alipay.sofa</groupId>
             <artifactId>tracer-enterprise-sofa-boot-starter</artifactId>
        </dependency>
    3. 修改全局配置项。

      application.properties 文件中,完成中间件全局配置。详情请参见 properties 配置项

    4. 实现处理器接口。

      客户端提供了 ISimpleJobHandler 接口给业务方实现,通过实现该接口编写业务逻辑代码。

      /**
       * 简单任务处理器接口。
       */
      public interface ISimpleJobHandler extends IJobHandler{
      
          /**
           * 处理 request。
           *
           * @param context
           * @return
           */
          ClientCommonResult handle(JobExecuteContext context);
      }

      代码说明:

      • JobExecuteContext 是触发任务的请求上下文,您可以从里面获取到任务的一些信息。例如在控制台创建任务时设置的自定义参数,可以通过 getCustomParam(String key) 方法获取。

      • 如果设置了任务分片,可以通过方法 getSharding() 获取当前机器分配到的分片号。详细信息可以查看 com.alipay.antschedulerclient.model.JobExecuteContext 这个类的源码。

    5. 实现类。

      类里必须分别实现 handlegetThreadPoolgetName 方法。

      • handle:在该方法里执行业务逻辑。

      • getThreadPool:获取一个执行该任务的线程池,如果没有设置,会使用客户端自带的线程池。

      • getName:获取这个执行器的名字。客户端接收到任务的触发请求时,会根据名字寻找匹配的执行器。

        说明

        当任务需要按多个步骤执行时,需要写多个实现类,并在控制台开启分步。

        代码示例如下:

        public class AlwaysSuccessHandler implements ISimpleJobHandler{
            private static final String NAME ="ALWAYS_SUCCESS_JOB";
            private static final ThreadPoolExecutor executor =new ThreadPoolExecutor(20,
                    300,1,TimeUnit.HOURS,new ArrayBlockingQueue<Runnable>(100){})
        
            /**
             * 处理业务逻辑。
             **/
            @Override
            public ClientCommonResult handle(JobExecuteContext context) throws InterruptedException{
                // 获取自定义参数。
                Integer num =(Integer) context.getCustomParam("num");
                if(num ==null){
                    num =0;
                }
                num = num +1;
                // 更新自定义参数。
                context.putCustomParams("num",5);
                return ClientCommonResult.buildSuccessResult();
            }
        
            @Override
            public ThreadPoolExecutor getThreadPool(){
                // 建议使用自定义实现类。
                return executor;
            }
        
            @Override
            public String getName(){
                // handler 名字,管控页面配置的 handler 即这部分定义内容。
                return NAME;
            }
        }
        
    6. 配置 Spring。

      通过以下任一方式将接口实现类配置为 Spring Bean:

      • src/main/resources/META-INF/xxx/xxx-xxx.xml 文件中进行配置。示例如下:

        <bean id="sampleService" class="com.antcloud.demo.antscheduler.service.SampleServiceImpl"/>
      • 使用注解驱动(annotation-driven)的方式声明 Bean。

  2. 在云端发布应用。

    本地客户端开发完成后,您需要将其发布部署到 SOFAStack 经典应用服务。详细步骤,请参见 发布部署应用

  3. 在控制台配置调度任务。

    1. 登录任务调度控制台。

    2. 在左侧导航栏选择 中间件 > 任务调度 > 任务配置

    3. 选择 添加任务 > 简单任务,然后配置以下参数:

      参数

      说明

      任务名称

      配置任务的名称,用于识别任务。

      应用名称

      填写或选择目标应用名称。

      必须与工程中 application.properties 文件的 spring.application.name 配置的应用名称一致。

      调度类型

      配置任务调度的类型,可选值:

      • cron 表达式触发:该类型的任务在创建时需要配置 CRON 表达式定时触发任务。

      • 事件触发:该类型的任务通过外部事件触发任务。

      • 定时触发:该类型的任务在创建时也需要配置 CRON 表达式定时触发,并且只能执行一次。

      Cron 表达式

      配置 CRON 表达式,用于定时触发任务。配置方式请参见 CRON 表达式详解

      仅在 调度类型cron 表达式触发 时配置。

      任务分组(可选)

      选择或新建一个任务分组,方便归纳管理任务。

      执行器名字

      必须与代码中任务处理器名字一致,即 实现类 步骤中 getName 方法获取的执行器名字。

      是否分片

      选择任务是否开启分片:

      • 不开启分片,任务将只调度到一台客户端服务器上执行。

      • 开启分片,并设置分片数为 N,任务则会同时触发到 N 台客户端服务器上并发执行。

        如果您开启了分片,您还需在本地工程编码实现任务分片。代码参见下文 任务分片示例代码

      自定义参数(可选)

      自定义参数支持从控制台向任务传递参数,参数也可以在任务间传递,格式为:key=value

      参数配置说明如下:

      • 参数名:设置自定义参数的名称。

        支持英文大小写、数字、下划线(_), 不能超过 128 字符。

      • 类型 参数值:可选类型和参数值配置方式如下。

        • STRING:支持通用的字符串。

        • LIST:支持字符串数组,例如:["aaa","bbb"]

        • BOOLEAN:支持 true 或 false。

        • PLACEHOLDER:支持参数替换,目前支持的变量如下:

          • ${sharding}:替换当前分片值,配合简单任务使用。

          • ${shardingCount}:替换简单任务配置的分片数。

          • ${triggerTime}:替换预期的触发时间。

      说明

      您也可以在业务端通过上下文 context(该对象必须实现 Serializable。)获取和覆盖自定义参数。代码参见下文 获取和覆盖自定义参数示例代码

      路由策略

      选择执行任务的路由策略,可选值:

      • 随机:每次执行都随机分发到客户端服务器上。

      • 定向:每次执行都分发到同一个客户端服务器上。

        暂不支持指定客户端服务器 IP。

      • 轮询:每次执行依次分发到每台客户端服务器上。

      通信方式

      选择任务的通信方式,可选值:

      • 单向 ONEWAY:单向操作,没有返回值。控制台不记录触发记录、无超时、无重试。

        高频非重要任务时建议使用。

      • 回调 CALLBACK:双向操作,有返回值。控制台可查看触发记录、可设置超时、可重试。

        重要任务时建议使用,触发间隔至少 5 分钟。

      任务互斥

      选择是否开启任务互斥模式。开启任务互斥模式时,处在“执行中”或“暂停”状态的任务即使已经达到下一个任务触发时间点,仍无法再次触发。本次调度状态以“跳过”标记。默认为不开启。

      仅当 通信方式 设置为 回调 CALLBACK 时配置。

      漏触发策略

      设置任务漏触发时的处理策略,可选值:

      • 忽略:不进行补偿处理。

      • 立即触发:立即重新触发。

      • 时间充裕时触发:是否进行补偿触发取决于下次触发前的剩余时间是否充裕。若当前时间 + 超时时间 < 下次触发时间,则进行补偿触发,并将此次补偿触发插入触发记录;反之,则不触发。多次漏触发进行恢复时仅进行一次补偿触发。

      仅当 通信方式 设置为 回调 CALLBACK,且 调度类型 cron 表达式触发 时,可配置此项。

      超时策略

      设置任务执行超时后的处理策略,可选值:

      • 不处理:触发记录和执行记录状态均标记为失败。

      • 按失败策略重试:本次调度记录状态标为失败,并按照 失败处理策略 进行失败重试。重试后本次调度记录将被重置为重试结果。

      • 停止后续触发:执行记录状态为失败,触发记录状态为超时,并且无法再次触发。仅当开启任务互斥模式时可选择此项。

      仅当 通信方式 设置为 回调 CALLBACK 时配置。

      超时时间

      设置任务执行的超时时间,当任务超过此时间未回调则认为执行失败。单位可选择为 分钟小时

      仅当 通信方式 设置为 回调 CALLBACK 时配置。

      失败处理策略

      设置任务执行失败后的处理策略,可选值:

      • 不重试:失败后不进行重试。

      • 最多重试三次:失败后立即进行重试,但最多重试三次。

      • 重试到下次触发:失败后立即进行重试,直到下次触发时间。

      优先级

      用于识别任务的重要性,暂无其他作用。

      默认为 中等

      描述(可选)

      配置任务的描述信息,例如业务含义、影响范围等,最多 1024 个字符。

      任务分片示例代码

      public class ShardingSchedule implements ISimpleJobHandler {
      
          private final Logger LOGGER = LoggerFactory.getLogger(ShardingSchedule.class);
      
          private ThreadPoolExecutor threadPool;
      
          @Override
          public String getName() {
              return "SHARDING_SCHEDULE";
          }
      
          @Override
          public ClientCommonResult handle(JobExecuteContext jobExecuteContext) throws Exception {
              int sharding = jobExecuteContext.getSharding();
      
              //当前机器获取到的分片数
              LOGGER.info("current machine sharding is " + sharding);
              //总的分片数
              System.out.println("total sharding num is " + jobExecuteContext.getShardingCount());
      
              System.out.println("activity sharding is" + jobExecuteContext.getActivitySharding());
      
              return ClientCommonResult.buildSuccessResult();
          }
      
          @Override
          public ThreadPoolExecutor getThreadPool() {
              return threadPool;
          }
      
       /**
           * Setter method for property threadPool.
           *
           * @param threadPool value to be assigned to property threadPool
           */
          public void setThreadPool(ThreadPoolExecutor threadPool) {
              this.threadPool = threadPool;
          }
      
      }

      获取和覆盖自定义参数示例代码

      public class SimpleTaskDemo implements ISimpleJobHandler {
      
          @Override
          public ClientCommonResult handle(JobExecuteContext context) {
             // 根据 key 获取 obj
              Object obj = context.getCustomParam("intObj");
      
              // 获取自定义参数
              Map<String, Object> paramsMap = context.getCustomParams();
              context.putCustomParams("num", 2);
              List<String> listparam = newArrayList <>();
              listparam.add("aaaaaa");
              listparam.add("111111");
              context.putCustomParams("intparam", 111);
              context.putCustomParams("stringparam", "dfadsfad1243");
              context.putCustomParams("listparam", listparam);
              // 注意对象必须实现 Serializable
              context.putCustomParams("objectParam", newObject());
              return ClientCommonResult.buildSuccessResult();
          }
      
      ....
      }
    4. 单击 提交

    5. 在任务列表中打开目标任务的 是否启用 开关。

      如果有客户端在线,新配置的任务自动有客户端注册。任务在禁用的状态下,您也可以在操作列单击 触发,手动触发一次任务。

      启用

查看任务调度记录

  1. 在任务列表中,单击目标任务名称。

  2. 单击 调度记录 页签,查看调度记录。

    调度记录最多保留 7 天。您可以使用页签上方的下拉列表筛选调度记录类型,包括全部调度记录、调度执行成功、调度执行失败以及漏调度记录。