spring @ schedule annotations How to dynamically configure time intervals

  • 2021-12-09 08:48:59
  • OfStack

Directory @ schedule Annotation Dynamic Configuration Time Interval spring Annotation Schedule Configuration Timing Task

@ schedule annotation dynamic configuration interval

Dynamic configuration time interval is realized by registering tasks to task scheduling, and changing the next scheduling time interval during each scheduling. If tasks are blocked or hung up, they will not be scheduled again. If the setting time is too long, it will take a long time to wait for the next scheduling.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component; 
import java.util.Date; 
 
@Component
@EnableScheduling
public class DynamicScheduleTaskSecond implements SchedulingConfigurer {
    private static final long WEEK_MILLIS = 604800000;
    private static final long MIN_MILLIS = 1000;
    private static long period = 1000;
    static long l = System.currentTimeMillis();
 
    @Autowired
    SetPeriod setPeriod; 
    public static long getPeriod() {
        return period;
    }
 
    public static void setPeriod(long period) {
        DynamicScheduleTaskSecond.period = period;
    }
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                try {
                    setPeriod.update(period);
                    System.out.println("abc");
                    Long last = System.currentTimeMillis() - l;
                    l = System.currentTimeMillis();
                    System.out.println(last);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                if (period < MIN_MILLIS || period > WEEK_MILLIS)
                    period = MIN_MILLIS;
                PeriodicTrigger periodicTrigger = new PeriodicTrigger(period);
                Date nextExecDate = periodicTrigger.nextExecutionTime(triggerContext);
                return nextExecDate;
            }
        });
    }
}
  
import org.springframework.stereotype.Component; 
@Component
public class SetPeriod { 
    private static Long maxPeriod = 1000l; 
    public void update(Long period) {
        maxPeriod += 1000;
        setScheduleConfig(maxPeriod);
    }
 
    public boolean setScheduleConfig(Long period) {
        DynamicScheduleTaskSecond.setPeriod(period);
        return true;
    }
}

The above is a simple example to realize dynamic scheduling, and the following is the basic principle.

The function of dynamic scheduling is mainly to realize SchedulingConfigurer functional interface, and the parameters of configureTasks method in the interface are the key points.


@FunctionalInterface
public interface SchedulingConfigurer {
 
 /**
  * Callback allowing a {@link org.springframework.scheduling.TaskScheduler
  * TaskScheduler} and specific {@link org.springframework.scheduling.config.Task Task}
  * instances to be registered against the given the {@link ScheduledTaskRegistrar}.
  * @param taskRegistrar the registrar to be configured.
  */
 void configureTasks(ScheduledTaskRegistrar taskRegistrar); 
}

Look at the name ScheduledTaskRegistrar, you will know that it is a scheduling task registration class, and calling the addTriggerTask method of this class requires two parameters


    public void addTriggerTask(Runnable task, Trigger trigger) {
        this.addTriggerTask(new TriggerTask(task, trigger));
    }

One is the task thread, and the last one is the second Trigger, which is an interface for setting the trigger time of tasks. The specific implementation has two classes, one is the time setting of CronTrigger corresponding to cron type, and the other is the time setting of FixDelay and FixRate corresponding to PeriodicTrigger, which is used in the example.


public interface Trigger {
    @Nullable
    Date nextExecutionTime(TriggerContext var1);
}

The interface method parameter is an TriggerContext, This parameter is the context of the task trigger, It stores the start time, end time and actual execution time of the last task, I need to implement this nextExecutionTime method to return a new Date time according to the last task execution time. The new1 new periodicTrigger objects initialize the period time interval to a new time interval, and the nextExecutionTime method can return a new task scheduling time according to the context time. However, the time of period can't be too long or too short, so it is best to set an interval, which can avoid the trouble caused by many careless errors, and perfectly solve the function of dynamically setting task scheduling time interval.

Let's talk about what needs to be done in the first thread task. The tasks performed need to be implemented in other concrete classes, Then call in this thread, and then reset the time interval according to the time service every time when scheduling tasks, such as changing the time interval after reading the configuration, that is, scheduling and specific tasks form a ring, and after scheduling and executing specific tasks, specific tasks set the scheduling time interval.

spring Annotated Schedule Configuration Timing Task


@Component
public class ScheduledTasks {
    @Autowired
    private ActivityService activityService;
//    1000 I.e. 1s
    @Scheduled(fixedRate = 1000)
    public void reportCurrentTime() {
        System.out.println(" Current time : " + DateUtil.getNow());
        log.info(" Print current time : {}.", DateUtil.getNow());
    }
    /* Every day 4 Point update 1 Times */
    @Scheduled(cron = "0 0 4 * * ? ")
    public void updateRankLIstToRedis() {
        /* redis Timeout setting  expire Setting multiple times overrides  */
        List<RankInfoDTO> list = activityService.countRankList(ACTIVITY_WEB);
    }
}

Quite simply, it should be noted that there are two kinds of setting time intervals, corn and fixedRate, one is suitable for a long time and can set a specific time, and the other is shorter.

cron, Baidu's first is a fool-like tool webpage, so don't be afraid not to write it.


Related articles: