All Products
Search
Document Center

SchedulerX:Spring jobs

Last Updated:Jan 29, 2024

Scheduled Spring jobs facilitate the application of scheduled jobs in a Java system but also have many limitations in enterprise scenarios. By connecting scheduled Spring jobs to SchedulerX, enterprises can use applications easily.

Prerequisites

Specify connection configurations

A Spring Boot application is used in the following example.

  • Add a dependency and a startup class to the pom.xml file of the application.

  • Replace schedulerx2.version with the latest version of the SchedulerX agent. For more information, see Agent release notes.

<dependency>
  <groupId>com.aliyun.schedulerx</groupId>
  <artifactId>schedulerx2-spring-boot-starter</artifactId>
  <version>${schedulerx2.version}</version>
  <!-- If you use Logback, you must exclude Log4j and 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>
  • Regardless of whether you use scheduled Spring jobs for the first time, keep @EnableScheduling enabled in the startup class. The following code provides an example.

@SpringBootApplication
@ EnableScheduling /**Enable scheduled Spring jobs.*/
public class SchedulerXWorkerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SchedulerXWorkerApplication.class, args);
    }
}

/** Native scheduled Spring job class*/
@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");
    }
}

For users who perform the preceding configurations for the first time or have performed the preceding configurations, SchedulerX does not take over the original scheduled Spring jobs in the business application by default. These jobs are still scheduled by the Spring container, and the execution of these jobs is not affected.

To run scheduled Spring jobs in the SchedulerX console, you can add the following configuration to the Properties file.

# Allow SchedulerX to take over scheduled Spring jobs.
spring.schedulerx2.task.scheduling.scheduler=schedulerx

After adding the preceding configuration, you can configure a job or configure automatic job synchronization to manage and schedule the job.

Configure a job

  1. Log on to the SchedulerX console.

  2. In the left-side navigation pane, click Task Management.

  3. On the Task Management page, click Create task. In the Create task panel, set the Task type parameter to SpringSchedule.

    Parameter

    Description

    Task name

    The name of the job.

    Description

    The description of the job. We recommend that you use simple descriptions to facilitate job management.

    Application ID

    The group to which the job belongs. Select an application ID from the drop-down list.

    Task type

    The programming language that you want to use to create the job. Valid values include Java, Shell, Python, Go, Http, Node.js, XXL-JOB, and DataWorks. When you select Shell, Python, or Go, an editor is displayed. You can enter a script in the editor.

    In this topic, SpringSchedule is selected.

    spring scheduleConfiguration

    The complete class name and method name of the job.

    Execution mode

    The mode in which the job is executed. The following execution modes are supported:

    • Stand-alone operation: The job is executed on a random worker.

    • Broadcast run: The job is concurrently executed on all workers, and the system waits until all workers complete the job.

    Note

    The advanced settings of a job vary based on the execution mode of the job.

    Priority

    If multiple jobs of the same application run on the same instance at the same time, jobs with high priorities are executed first. However, if multiple jobs of the same application run on multiple instances, jobs with different priorities are scheduled to different instances. In this case, jobs with low priorities may be executed first. SchedulerX uses preemptible queues to avoid this issue and ensure that a job with a higher priority in a queue is triggered first. For more information, see Preemptible queues.

    Task parameters

    An arbitrary string that can be obtained from the context when SchedulerX runs the job.

  4. Configure the trigger frequency.

    Note

    The frequency that is specified in the SchedulerX console prevails, and the configuration of the native annotation @Scheduled in the code of the scheduled Spring job becomes invalid. However, the annotation is retained in the code.

    The following table describes the parameters.

    Parameter

    Description

    Time type

    • none: In most cases, the job is triggered by using a workflow.

    • cron: The job is scheduled based on a cron expression.

    • api: The job is triggered by using an API operation.

    • fixed_rate: The job is triggered at a specified interval.

    • second_delay: The job is triggered with a delay from 1 to 60 seconds.

    • one_time: The job is triggered only once at the specified time.

    cron expression (available only when the Time type parameter is set to cron)

    Enter a cron expression that complies with the cron syntax or use the tool that is provided by SchedulerX to generate an expression. Then, verify the cron expression.

    Fixed frequency (available only when the Time type parameter is set to fixed_rate)

    Specify the interval at which the job is triggered. The value must be greater than 60. Unit: seconds. For example, the value 200 indicates that the job is triggered at an interval of 200 seconds.

    Fixed delay (available only when the Time type parameter is set to second_delay)

    Specify a fixed delay. Valid values: 1 to 60. Unit: seconds. For example, the value 5 indicates that the job is triggered with a delay of 5 seconds.

    The following table describes the advanced timing configurations.

    Parameter

    Description

    Time offset

    The offset between the timestamp of the data to be processed and the time when the job is triggered. You can obtain the offset value from the context when SchedulerX runs a job.

    Time zone

    Select the time zone of a country or region or select a GMT time zone based on your business requirements.

  5. Configure alert conditions and the notification channel. For more information about the notification channel, see Notification contacts and notification contact groups.

    After you complete the configurations, SchedulerX can run scheduled Spring jobs. The console also provides native Spring jobs with enterprise-level O&M capabilities, including visualized management and control, job log query, execution chain view, and job execution notification and alerting.

Configure automatic job synchronization

If you already use scheduled Spring jobs and have many scheduled jobs that are to be executed, you can enable automatic job synchronization in the application configuration file. This way, you do not need to perform the preceding manual configurations. The following example describes the Properties configuration.

# Allow SchedulerX to take over scheduled Spring jobs and enable automatic job synchronization.
spring.schedulerx2.task.scheduling.sync=true
# If automatic parameter synchronization is enabled, you must configure the following additional parameters. Otherwise, you do not need to configure the following parameters. 
spring.schedulerx2.regionId=The ID of the region to which you want to synchronize the jobs (For more information about region IDs, see Endpoints.)
spring.schedulerx2.aliyunAccessKey=XXXXXXXXX
spring.schedulerx2.aliyunSecretKey=XXXXXXXXX

The following table shows the IDs of specific regions. For more information, see Endpoints.

Region name

Region ID

Public endpoint

VPC endpoint

China (Hangzhou)

cn-hangzhou

schedulerx.aliyuncs.com

schedulerx-vpc.cn-hangzhou.aliyuncs.com

China (Shanghai)

cn-shanghai

schedulerx.aliyuncs.com

schedulerx-vpc.cn-shanghai.aliyuncs.com

Internet

public

schedulerx.aliyuncs.com

N/A

Important

To ensure that the running rule of a job that is automatically synchronized is the same as that of native Spring jobs in a cluster, the system sets the Execution mode parameter of the job that is automatically synchronized to Broadcast run by default. This way, every worker in the cluster runs the job at the specified point in time. If a job needs to be automatically run on a worker in the cluster, set the Execution mode parameter of the job to Stand-alone operation in the SchedulerX console. For more information about the parameter, see Configure a job.

FAQ

Why does the original Spring timer still run after SchedulerX takes over scheduled Spring jobs?

If a custom scheduler is specified in your application, SchedulerX overwrites the custom scheduler. Check whether the class that implements the org.springframework.scheduling.annotation.SchedulingConfigurer interface exists in your application project, and whether the setScheduler method of ScheduledTaskRegistrar is invoked to overwrite the default scheduler.

How do I obtain the context for a Spring job?

Add the following code to your application project code to obtain the context:

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

Does a Spring job return a processing result?

When the version of your client is later than 1.10.11, Spring jobs can return processing results. The processing results are returned based on the specified scheduling methods.

@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, "Processing result");
}

@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 "Processing result";
}