Problèmes d'utilisation ressort @Scheduled

Christian Bombazar:

J'ai trois méthodes sur mon projet annotés avec @Scheduled, étant l'un d'entre eux une expression de Cron et les deux autres sont retard fixe. Les annotations ressemblent:

Méthode 1:

@Scheduled(fixedDelay = 20000)
@Async
protected void checkBrokenEngines() {

Méthode 2:

@Scheduled(fixedRate = 20000)
@Async
public void checkAvailableTasks() throws Exception {

Méthode 3:

@Scheduled(cron = "0 0 2 * * ?")
protected void deleteOldData() {

Auparavant , j'avais un problème que lorsque les checkBrokenEngineset checkAvailableTasksméthodes ont été lents à exécuter, les prochaines exécutions n'a pas eu lieu jusqu'à ce que le précédent a pris fin. La lecture de la documentation et des sujets ici de la StackOverflow, j'ai vu que mon projet avait quelques mauvaises taille de la piscine les paramètres et les méthodes non - annotés avec async . (Async était pour la prochaine début d' exécution , même si l'ancien ne se termine pas, car cela ne pose aucun problème dans ma demande)

Maintenant, un autre problème est venu, ce qui est ma question:

Lorsque la deleteOldData()méthode est exécutée, aucune des deux autres méthodes se déroulera jusqu'à ce qu'il se termine. Après avoir vu que cette méthode bloquait l'exécution des deux autres, la méthode que j'annotés comme async et après que, même si cette méthode prend du temps à exécuter, les deux autres sont toujours correctement invoqué dans les délais impartis. Pourquoi? Dans ma compréhension, cela ne devrait pas se produire puisque ces méthodes sont notées avec async et la piscine a assez d' espace pour les exécuter.

PS: deleteOldData()ne peut pas être async. Il doit commencer juste après l'exécution précédente est terminée.

EDIT 1:

Async config exécuteur:

@Override    
public AsyncTaskExecutor getAsyncExecutor() {
    log.debug("Creating Async Task Executor");
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(50);
    executor.setMaxPoolSize(50);
    executor.setQueueCapacity(10000);        
    return new ExceptionHandlingAsyncTaskExecutor(executor);
}
Sagar Veeram:

Toutes @Scheduled les invocations marquées utiliseront l'exécuteur unique de threads par défaut pour programmer des tâches (async ou autre).

Toutes les @Asynctâches sont remis à différents hors exécuteur threadpool de aysnc pour les exécutions avec intercepteurs AOP.

Je pense que votre confusion vient du fait async méthodes renvoient immédiatement mais quand deleteOldData est exécuté, il est en cours d' exécution synchrone car il n'y a qu'un seul thread, il bloque l'exécution de toutes les autres tâches prévues.

Parce que vous avez threadpool par défaut (un seul thread) pour les tâches planifiées qu'ils sont programmées l'une après l'autre.

Les autres méthodes annotées avec @Async ils exécutent même si elle se termine ou non. Dans certains cas, j'ai deux méthodes d'exécution en même temps. Mais quand deleteOldData est en cours d'exécution, les méthodes async arrêtent pour courir jusqu'à ce qu'il se termine. Ce que je ne comprends pas, désolé: / -

Ceci est différent de la programmation - C'est là votre exécuteur testamentaire async entre en jeu et ils sont appliquées simultanément.

Vous pouvez résoudre ce problème dans l'une des deux façons suivantes:

Vous pouvez utiliser spring.task.scheduling.pool.size=10les propriétés d'application pour définir la taille de la piscine du planificateur de tâches.

Vous pouvez également utiliser différentes tâches ordonnanceurs. Continuez à utiliser ordonnanceur par défaut pour @Scheduledquelque chose de tâche et configurer comme ci - dessous pour les tâches asynchrones (supprimer l' annotation prévue)

Il y a une amélioration demandé de transmettre le planificateur de tâches à l' @Scheduledannotation jusqu'à ce que vous devez planifier les tâches manuellement.

Enregistrer un nouveau planificateur de tâches pour les invocations async et de planifier les méthodes dans la phase post-construction. Quelque chose comme

Configuration

@Bean("asyncTaskScheduler")
public TaskScheduler asyncTaskScheduler() {
  return new ThreadPoolTaskScheduler();
}

Prestations de service

@Autowired
private TaskScheduler asyncTaskScheduler;

@PostConstruct
void schedule() {
  asyncTaskScheduler.scheduleAtFixedRate(this::checkAvailableTasks, 20000L);
  asyncTaskScheduler.scheduleAtFixedDelay(this::checkBrokenEngines, 20000L);
}

@Async
public void checkBrokenEngines() {...}

@Async
public void checkAvailableTasks() throws Exception {...}

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=370181&siteId=1
conseillé
Classement