文档

Spring任务

更新时间:
一键部署

Spring定时任务为您在Java体系下定时任务开放提供了便捷方式,但其便捷的同时也有很多企业化场景下的局限性。通过对接SchedulerX任务调度可快速实现企业化运用的支持。

前提条件

接入指南

接入配置

以Spring Boot接入模式为例,应用程序的pom.xml文件中添加依赖及启动类。

schedulerx2.version使用客户端最新版本。更多信息,请参见客户端发布记录

<dependency>
  <groupId>com.aliyun.schedulerx</groupId>
  <artifactId>schedulerx2-spring-boot-starter</artifactId>
  <version>${schedulerx2.version}</version>
  <!--如果用的是logback,需要把log4j和log4j2排掉 -->
  <exclusions>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </exclusion>
  </exclusions>
</dependency>

无论是已经使用Spring定时任务或初次使用,都需要在启用类上保持@EnableScheduling注解开启。如下所示:

@SpringBootApplication
@EnableScheduling /** 开启Spring定时任务 */
public class SchedulerXWorkerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SchedulerXWorkerApplication.class, args);
    }
}

/** Spring原生配置的定时任务类*/
@Service
public class SpringScheduledProcessor {
    @Scheduled(cron = "0/2 * * * * ?")
    public void hello() {
        logger.info(DateUtil.now() + " hello world. start");
        logger.info(DateUtil.now() + " hello world. end");
    }
}

对于新接入上述配置或已经满足上述配置的用户,SchedulerX默认不会主动接管业务应用中原本的Spring定时任务,相应定时任务还是会由Spring容器进行调度,不影响原本已有的Spring定时任务运行。

后续业务需要让SchedulerX任务调度平台来接管Spring定时任务的运行,则可以在Properties文件中添加如下配置。

# 启用SchedulerX接管Spring定时任务
spring.schedulerx2.task.scheduling.scheduler=schedulerx

添加完成后,就可以通过下文中任务配置运行或任务自动同步进行任务管控配置和定时运行了。

任务配置运行

  1. 登录分布式任务调度平台

  2. 在左侧导航栏,单击任务管理

  3. 任务管理页面,单击创建任务。选择springschedule任务类型,配置对应定时任务类及其方法名。

    配置名称

    意义

    任务名

    任务名称。

    描述

    任务描述,尽量简洁地描述业务,便于后续搜索。

    应用ID

    任务所属分组。可以在下拉列表中选择。

    任务类型

    指任务所实现的语言,当前支持Java、Shell、Python、Go、http、Node.js、xxljob和DataWorks类型,其中Shell、Python和Go会弹出编辑框,在编辑框中编写任务脚本。

    本文任务类型为springschedule。

    spring schedule配置

    定时任务代码的完整类名(class name)和任务的方法名(method name)。

    执行模式

    执行模式,这里特指任务执行的模式,当前支持以下模式。

    • 单机运行:随机选一台机器执行。

    • 广播运行:所有机器同时执行并等待全部结束。

    说明

    当选择了不同的执行模式后,高级设置中的参数会随之变化。

    优先级

    同一应用下多个任务同时在一个实例中运行时,优先级高的任务会被优先执行。但当一个应用中的多个应用在多个实例中运行时,不同优先级的任务被调度到不同实例执行,可能导致低优先级任务被优先执行。SchedulerX通过可抢占的优先级队列规避了这种可能性,并保证同时在池子中等待的高优先级任务被优先执行。更多信息,请参见可抢占的优先级队列

    任务参数

    任意字符串,可以在运行时通过上下文获取。

  4. 配置对应定时触发频率。

    说明

    频率会以控制台配置的频率为准,Spring定时任务代码中原生注解@Scheduled中配置将会失效,但该注解在代码中需要保留。

    定时参数说明如下:

    配置名称

    意义

    时间类型

    • none:无调度方式,一般通过工作流触发。

    • cron:Cron表达式。

    • api:通过API触发。

    • fixed_rate:固定频率。

    • second_delay:秒级固定延迟。

    • one_time:一次性任务。

    cron表达式(仅适用于cron时间类型)

    填写Cron表达式。可以直接按照Cron语法填写,也可以使用工具生成并验证。

    固定频率(仅适用于fixed_rate时间类型)

    填写固定频率,单位为秒,只支持60秒以上。例如200表示每200s调度一次。

    固定延迟(仅适用于second_delay时间类型)

    填写固定延迟,单位为秒。范围为1秒~60秒。例如5表示延迟5秒触发调度。

    高级配置参数说明如下:

    配置名称

    意义

    时间偏移

    数据时间相对于调度时间的偏移,可以在调度时从上下文获取该值。

    时区

    可以根据实际情况选择不同时区,包括一些常用国家或地区,也包括标准的GMT表达方式。

  5. 设置相关报警条件和通知渠道等。关于通知渠道,请参见通知联系人和通知联系人组

    完成上述步骤后,SchedulerX任务调度平台即可接管运行Spring的定时任务,支持为原生的Spring任务带来的各种可视化管控、任务业务日志查询、执行链路查看、任务执行通知报警等企业级能力。

任务自动同步

原本已使用Spring定时任务且存量定时任务较多的用户,可以选择在应用配置文件中开启自动同步任务,大幅度简化上述手动创建的过程。Properties配置参考如下。

# SchedulerX接管Spring定时任务,开启自动同步任务
spring.schedulerx2.task.scheduling.sync=true
# 在开启自动同步参数情况下,需额外配置以下参数。如果自动同步未开启则如下参数可不配置。
spring.schedulerx2.regionId=同步至目标区域编号(关于RegionId请参见服务接入点)
spring.schedulerx2.aliyunAccessKey=XXXXXXXXX
spring.schedulerx2.aliyunSecretKey=XXXXXXXXX

部分地域的RegionId如下所示。更多信息,请参见服务接入点

地域名称

地域ID

公网接入地址

VPC接入地址

华东1(杭州)

cn-hangzhou

schedulerx.aliyuncs.com

schedulerx-vpc.cn-hangzhou.aliyuncs.com

华东2(上海)

cn-shanghai

schedulerx.aliyuncs.com

schedulerx-vpc.cn-shanghai.aliyuncs.com

公网

public

schedulerx.aliyuncs.com

重要

自动同步的任务为了保持与原生Spring任务在集群环境中运行的规则一致,默认同步至平台上的任务执行模式为广播运行(即集群中每台机器都会在相应时点执行该任务)。如果业务需要自动在集群机器中选择一个运行,可在控制台编辑相应任务执行模式为单机运行。关于参数的详细信息,请参见任务配置运行

常见问题

SchedulerX接管后原Spring定时器依旧运行

由于应用中配置了自定义的Scheduler调度器导致SchedulerX覆盖自定义处理器。请排查业务应用工程中是否存在实现org.springframework.scheduling.annotation.SchedulingConfigurer接口的类,确认是否调用了ScheduledTaskRegistrar的setScheduler方法覆盖默认调度器。

Spring任务如何获取任务上下文

在业务应用工程代码中增加以下代码获取任务上下文。

JobContext jobContext = ContainerFactory.getContainerPool().getContext();

Spring任务是否支持返回结果

版本客户端大于1.10.11时,Spring任务支持返回结果,您可直接在定时方法上返回任意结果。

@Scheduled(cron = "0/5 * * * * ?")
public ProcessResult helloStandalone1() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    return new ProcessResult(true, "执行结果信息");
}

@Scheduled(cron = "0/5 * * * * ?")
public String helloStandalone2() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    return "执行结果信息";
}

  • 本页导读 (1)
文档反馈