Spring Boot 2. x Basic Tutorial Method of Using @ Scheduled to Implement Timing Tasks

  • 2021-10-27 07:32:59
  • OfStack

We often encounter such scenarios when writing Spring Boot applications, for example, I need to send some short messages and emails regularly, and I may also check and monitor some flags and parameters regularly.

Create a timed task

It is very simple to write timing tasks in Spring Boot. The following examples introduce how to create timing tasks in Spring Boot to output 1 current time every 5 seconds.

Add to the main class of Spring Boot @EnableScheduling Comments to enable configuration of timed tasks


@SpringBootApplication
@EnableScheduling
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}

Create a timed task implementation class


@Component
public class ScheduledTasks {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        log.info(" Now time: " + dateFormat.format(new Date()));
    }

}

Run the program, and you can see output like the following in the console, and the timed task starts to work normally.

2021-07-13 14:56:56.413 INFO 34836 --- [ main] c.d.chapter71.Chapter71Application : Started Chapter71Application in 1.457 seconds (JVM running for 1.835)
2021-07-13 14:57:01. 411 INFO 34836--[scheduling-1] com. didispace. chapter71. ScheduledTasks: Now time: 14:57:01
2021-07-13 14:57:06. 412 INFO 34836--[scheduling-1] com. didispace. chapter71. ScheduledTasks: Now time: 14:57:06
2021-07-13 14:57:11. 413 INFO 34836--[scheduling-1] com. didispace. chapter71.ScheduledTasks: Now time: 14:57:11
2021-07-13 14:57:16. 413 INFO 34836--[scheduling-1] com. didispace. chapter71.ScheduledTasks: Now time: 14:57:16

@Scheduled Detailed explanation

In the starter example above, the @Scheduled(fixedRate = 5000) Annotations to define tasks to be performed every 5 seconds. For @Scheduled Use, let's look at what configurations are available from the source code:


@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {

	String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED;

	String cron() default "";

	String zone() default "";

	long fixedDelay() default -1;

	String fixedDelayString() default "";

	long fixedRate() default -1;

	String fixedRateString() default "";

	long initialDelay() default -1;

	String initialDelayString() default "";

}

These specific configuration information have the following meanings:

cron: Configure execution rules through cron expressions zone: The time zone used when the cron expression is resolved fixedDelay: The time between the end of the last execution and the start of the next execution (in ms) fixedDelayString: The interval between the end of the last task execution and the start of the next task execution, parsed using java. time. Duration # parse fixedRate: Execute tasks at fixed intervals, that is, the interval between the start of the last task execution and the start of the next one (unit: ms). If the last task has not been completed when the task is scheduled to be executed, it will join the worker queue and wait for the next task to be executed immediately after the last one is completed fixedRateString: corresponds to fixedRate Logic 1, only using java. time. Duration # parse parsing initialDelay: Delay time for first task execution initialDelayString: Delay time for first task execution, parsed using java. time. Duration # parse

Thinking and Advanced

Is it easy to realize timing tasks in this way? So continue to think about whether there are any drawbacks in this implementation.

It may not be easy for beginners to find the problem, but if you have already had a certain online project experience, the problem is also obvious: the timed tasks implemented in this mode lack the coordination mechanism in the cluster environment.

What do you mean? Suppose that we want to implement a timed task, which is used to count some data online every day and then accumulate it on the original data. There will be no problem when we develop tests, because they are all running in a single process. However, when we deploy such timed tasks to a production environment, it is necessary to start multiple instances for higher availability. At this time, when time 1 arrives, all started instances will start executing this task at the same time. Then there is a problem, because there is an accumulation operation, and finally our results will be problematic.

There are many ways to solve this problem. The more common one is to use distributed lock to control the execution sequence before similar tasks. For example, using middleware with distributed lock function such as Redis and Zookeeper can help us coordinate the execution rules of such tasks in cluster mode.

Code Sample

The complete project of this article can be viewed in the following warehouse chapter7-1 Directory:

Github: https://github.com/dyc87112/SpringBoot-Learning/

Gitee: https://gitee.com/didispace/SpringBoot-Learning/


Related articles: