Maison  >  Article  >  Java  >  Comment implémenter plusieurs tâches planifiées dans Spring Boot

Comment implémenter plusieurs tâches planifiées dans Spring Boot

Java后端技术全栈
Java后端技术全栈avant
2023-08-15 16:50:341441parcourir

Dans le développement réel, nous utiliserons plus ou moins certains scénarios de tâches planifiées. Cet article parlera des tâches planifiées couramment utilisées.

Les solutions de mise en œuvre de tâches planifiées couramment utilisées sont les suivantes :

  • Timer : c'est l'automatique de Java Avec la classe java.util.Timer, cette classe permet de planifier un java.util.TimerTaskTâche. L'utilisation de cette méthode permet à votre programme d'être exécuté à une certaine fréquence, mais pas à une heure spécifiée. Généralement moins utilisé. Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
  • ScheduledExecutorService:也jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
  • Spring TaskSpring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
  • Quartz
  • ScheduledExecutorService : également jdk depuis Une classe fournie avec : est une classe de tâches planifiées basée sur la conception du pool de threads. Chaque tâche planifiée sera affectée à un thread du pool de threads pour son exécution. En d'autres termes, les tâches sont exécutées simultanément et ne s'affectent pas.
  • Spring TaskSpring3.0Les tâches qui viennent plus tard peuvent l'être ressemble à un quartz léger et est beaucoup plus simple à utiliser que le quartz.
    Quartz : Ceci est un Un planificateur relativement puissant peut permettre à votre programme d'être exécuté à une heure précise ou à une certaine fréquence, ce qui est un peu compliqué à configurer.
  • Dans la base de données, créez une table et stockez les expressions cron dans la table.

nacos, utilise une configuration distribuée pour implémenter une configuration dynamique expressions cron.

XXL-JOB, tâche fixe distribuée

🎜🎜🎜Utilisation de Timer🎜🎜 🎜🎜🎜Ceci est actuellement moins utilisé dans le projet, et le code de démonstration est directement publié. 🎜🎜Pour une introduction détaillée, veuillez consulter l'API : 🎜
public class TestTimer {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("task  run:"+ new Date());
            }
        };
        Timer timer = new Timer();
        //安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
        timer.schedule(timerTask,10,3000);
    }
}

Utiliser ScheduledExecutorService

Cette méthode est similaire à Timer, il suffit de regarder la démo :

public class TestScheduledExecutorService {
    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 参数:1、任务体 2、首次执行的延时时间
        //      3、任务执行间隔 4、间隔时间单位
        service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
    }
}

Utiliser Spring Task

Tâche planifiée simple

Dans le projet Spring Boot, nous pouvons l'utiliser annotation très élégante pour implémenter les tâches planifiées, créez d'abord un projet, importez les dépendances :

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

Créez une classe de tâches :

@Slf4j
@Component
public class ScheduledService {
    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
    }
    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
    }
    @Scheduled(fixedDelay = 5000)
    public void scheduled2() {
        log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
    }
}

Utilisez l'annotation @EnableScheduling sur la classe principale pour activer la prise en charge des tâches planifiées, puis démarrez le projet

Comment implémenter plusieurs tâches planifiées dans Spring Boot

Vous pouvez voir trois Toutes les tâches planifiées ont été exécutées, et elles sont exécutées en série dans le même thread. S'il n'y a qu'une seule tâche planifiée, ce n'est certainement pas un problème lorsque le nombre de tâches planifiées augmente, si une tâche est planifiée. bloqué, les autres tâches ne pourront pas s'exécuter.

Exécution multithread

Dans les projets Spring traditionnels, nous pouvons ajouter la configuration des tâches dans le fichier de configuration XML. Dans les projets Spring Boot, nous utilisons généralement la classe de configuration config pour ajouter la configuration, créez donc un nouveau AsyncConfig classe AsyncConfig

@Configuration
@EnableAsync
public class AsyncConfig {
     /*
    此处成员变量应该使用@Value从配置中读取
     */
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

@Configuration:表明该类是一个配置类@EnableAsync:开启异步事件的支持

然后在定时任务的类或者方法上添加@Async

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

@Configuration : indique que la classe est une classe de configuration@EnableAsync : activez la prise en charge des événements asynchrones

Comment implémenter plusieurs tâches planifiées dans Spring BootPuis dans la classe ou la méthode de la tâche planifiée Ajoutez @Async . Enfin redémarrez le projet, chaque tâche est dans un thread différent.

Configuration du temps d'exécution🎜🎜Dans la tâche planifiée ci-dessus, nous utilisons l'annotation @Scheduled sur la méthode pour définir le temps d'exécution de la tâche, et utilisons trois méthodes de configuration d'attributs : 🎜
  1. fixedRate : définissez une tâche planifiée qui est exécutée à une certaine fréquence.
  2. fixedDelay : définissez une tâche planifiée qui est exécutée à une certaine fréquence. La différence par rapport à ce qui précède est que la modification de l'attribut peut coopérer avec initialDelay pour. définir le délai d'exécution différé de la tâche.
  3. cron : Configurez le temps d'exécution des tâches via des expressions

Explication détaillée des expressions cron

Une expression cron comporte au moins 6 (peut-être 7) éléments temporels séparés par des espaces. Dans l'ordre :

  • secondes (0~59)
  • minutes (0~59)
  • 3 heures (0~23)
  • 4 jours (0~31)
  • 5 mois (0~11)
  • 6 semaines (1~7 1=DIM ou DIM, LUN, MAR, MER, JEU, VEN, SAM)
  • Année (1970-2099)

Chaque élément peut être une valeur (telle que 6), un intervalle continu (9-12), un intervalle (8-18/4) (/ signifie toutes les 4 heures), une liste (1, 3, 5), un caractère générique. Étant donné que les deux éléments « jour du mois » et « jour de la semaine » s'excluent mutuellement, l'un d'eux doit être défini. Exemple de configuration :

  • Exécuté toutes les 5 secondes : */5* * ?
  • Exécuté toutes les 1 minute : 0 /1 ?
  • 0 0 10,14,16 ?
  • 0 0/30 9-17 ? Toutes les demi-heures pendant 9 à 5 heures de travail
  • 0 0 12 ? * MER signifie tous les mercredis à 12h
  • " 0 0 12 ? " à 12h
  • "0 15 10 ? "Déclenchement tous les jours à 10h15
  • "0 15 10 ?" Déclenchement tous les jours à 10h15
  • "0 15 10 ? *" Déclenché tous les jours à 10h15
  • "0 15 10 ? 2005" Déclenché tous les jours à 10h15 en 2005
  • "0 14 * ?" Déclenché toutes les 1 minutes pendant 59
  • "0 0/5 14 ?" Déclenché toutes les 5 minutes de 14h à 14h55 tous les jours
  • "0 0/5 14,18 ?" à 14h55 et toutes les 5 minutes de 18h à 18h55
  • "0 0-5 14 ?" Déclenché toutes les 1 minutes de 14h à 14h05 tous les jours Déclencheur
  • "0 10,44 14 ? 3 MER" Déclenché tous les mercredis du mois de mars à 14h10 et 14h44
  • "0 15 10 ? * LUN-VEN" Lundi au vendredi matin Déclenché à 10h15
  • "0 15 10 15* ?" Déclenché à 10h15 le 15 de chaque mois
  • "0 15 10 L* ?" Déclenché à 10h15 le dernier jour de chaque mois
  • "0 15 10 * 6L" Déclenché le dernier vendredi de chaque mois à 10h15
  • "0 15 10 ? *6L 2002-2005" Déclenché le dernier vendredi de chaque mois à 10h de 2002 à 2005 :15 déclencheurs
  • " 0 15 10 ? * 6#3" Se déclenche à 10h15 le troisième vendredi de chaque mois

Certaines sous-expressions peuvent contenir des plages ou des listes

Par exemple : sous-expression La formule (jour (semaine)) peut être "MON-FRI", "MON, WED, FRI", "MON-WED, SAT"

Le caractère "*" représente toutes les valeurs possibles Le caractère "/" est utilisé pour préciser l'incrément de la valeur

Par exemple : "0/15" dans la sous-expression (minutes) signifie à partir de la minute 0, toutes les 15 minutes "3/20" dans la sous-expression (minutes) signifie qu'à partir de la 3ème minute, toutes les 20 minutes (il a la même signification que "3, 23, 43")

Le caractère "?" Deux sous-expressions (mois) et jour (semaine), indiquant qu'aucune valeur n'est spécifiée Lorsqu'une valeur est attribuée à l'une des deux sous-expressions, afin d'éviter les conflits, la valeur de l'autre sous-expression doit être définie sur "?"

Le caractère "L" n'est utilisé que pour le jour (mois) et le jour (semaine). ) ) deux sous-expressions, qui sont l'abréviation du mot "dernier" S’il y a quelque chose de spécifique avant le « L », cela a d’autres significations.

Par exemple : "6L" signifie le 6ème jour jusqu'à la fin de ce mois Remarque : lorsque vous utilisez le paramètre "L", ne spécifiez pas de liste ou de plage car cela entraînerait des problèmes.

Le caractère W représente les jours de la semaine (du lundi au vendredi) et ne peut être utilisé que dans le domaine du jour. Il est utilisé pour spécifier le jour de la semaine le plus proche de la date spécifiée. La plupart des traitements commerciaux sont basés sur la semaine de travail, le caractère W peut donc être très important.

Par exemple, 15W dans le champ jour signifie "le jour de la semaine le plus proche du 15 du mois". Si le 15 est un samedi, alors le déclencheur sera déclenché le 14 (vendredi), car le jeudi est plus proche du jour. Le 15 que lundi fermé.

C : signifie « Calendrier ». Cela signifie la date associée au planning, ou toutes les dates du calendrier si la date n'est pas associée.

Par exemple, 5C dans le champ date équivaut au premier jour après le 5 du calendrier. 1C dans le champ jour de la semaine correspond au premier jour après dimanche.

0 ~59, - * + , - * /semaine1~7 ou SUN~SAT, - * ? / L C #année (facultatif)laisser vide, 1970~2099, - * /

在线cron表达式生成:http://qqe2.com/cron/index

整合Quartz

  • 添加依赖

如果Spring Boot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

如果是1.5.9则要使用以下添加依赖:

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
</dependency>

这里我使用Spring Boot版本是2.0.0.BUILD-SNAPSHOT ,该版本开始集成了Quartz,所以事实现起来很方便。其它好像比较麻烦,这里就不介绍,以后有时间再详细深入了解Quartz。

  • 创建任务类TestQuartz,该类主要是继承了QuartzJobBean
public class TestQuartz extends QuartzJobBean {
    /**
     * 执行定时任务
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("quartz task "+new Date());
    }
}
  • 创建配置类QuartzConfig
@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail teatQuartzDetail(){
        return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build();
    }

    @Bean
    public Trigger testQuartzTrigger(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)  //设置时间周期单位秒
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
                .withIdentity("testQuartz")
                .withSchedule(scheduleBuilder)
                .build();
    }
}
  • 启动项目

Comment implémenter plusieurs tâches planifiées dans Spring Boot

最后

上面都是简单的介绍了关于Spring Boot定时任务的处理,直接使用SpringTask注解的方式应该是最方便的,而使用Quartz从2.0开始也变得很方便。对于这两种方式,应该说各有长处吧,按需选择。

Champ valeurs autorisées caractères spéciaux autorisés
secondes 0~59 , - *

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer