Problemas con el uso de primavera @Scheduled

Cristiano Bombazar :

Tengo tres métodos en mi proyecto anotados con @Scheduled, siendo uno de ellos una expresión cron y el retardo de los otros dos son fijos. Las anotaciones se parecen:

Método 1:

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

Método 2:

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

Método 3:

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

Anteriormente he tenido un problema que cuando el checkBrokenEnginesy checkAvailableTasksmétodos eran lentos para ser ejecutados, los siguientes ejecuciones no ocurrió hasta que terminó la anterior. La lectura de la documentación y algunos temas aquí desde el StackOverflow, vi que mi proyecto tenía algunas equivocadas tamaño piscina de configuración y los métodos no fueron anotados con asíncrono . (Asíncrono fue para la siguiente ejecución comenzar incluso si el viejo no termina, ya que esto no causa ningún problema en mi solicitud)

Ahora, otro problema ha surgido, que es mi pregunta:

Cuando el deleteOldData()se ejecuta método, ninguno de los otros dos métodos se ejecutará hasta que termine. Después de ver que este método estaba bloqueando la ejecución de los otros dos, me anotada como el método asíncrono y después de eso, aunque este método requiere tiempo para ser ejecutado, los otros dos están siempre invoca correctamente dentro del tiempo estipulado. ¿Por qué? A mi entender, esto no debería ocurrir, ya se ha señalado con esos métodos asíncrono y la piscina tiene espacio suficiente para ejecutarlos.

PD: deleteOldData()no puede ser asíncrona. Debe comenzar justo después de la ejecución anterior se ha completado.

EDIT 1:

Asíncrono ejecutor de configuración:

@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:

Todas las @Scheduled invocaciones marcados utilizarán el único ejecutor hilo por defecto a programar tareas (asíncrono o de otra manera).

Todas las @Asynctareas se traspasa a la diferente ejecutor aysnc subprocesos para las ejecuciones con AOP interceptor.

Creo que su confusión proviene del hecho asíncrono métodos devuelven inmediatamente pero cuando se ejecuta deleteOldData, que se ejecuta de forma sincrónica ya que sólo hay un hilo, bloquea la ejecución de todas las demás tareas programadas.

Debido a que tiene subprocesos predeterminado (hilo sencillo) para las tareas programadas que se han programado una después de la otra.

Los otros métodos anotados con @Async ejecutan incluso si se termina o no. En algunos casos, tengo dos métodos para ejecutar al mismo tiempo. Pero cuando deleteOldData está ejecutando, los métodos asincrónicos se detienen a correr hasta que termine. Esto lo que no estoy entendiendo, lo siento: / -

Esto es diferente de la programación - Aquí es donde su ejecutor asíncrono entra en juego y que se ejecutan concurrentemente.

Puedes solucionar este problema en una de dos maneras:

Se puede utilizar spring.task.scheduling.pool.size=10en las propiedades de aplicación para ajustar el tamaño de la piscina del programador de tareas.

Como alternativa, utilizar diferentes tareas programadores. Siga usando el planificador predeterminado para @Scheduledla tarea y configure similar a continuación para eliminar las tareas asíncronas (anotación programada)

No es una mejora solicitada para pasar programador de tareas para la @Scheduledanotación hasta entonces se tiene que programar tareas manualmente.

El registro de un nuevo programador de tareas para las invocaciones asíncronas y programar los métodos en la etapa posterior a la construcción. Algo como

Configuración

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

Servicios

@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 {...}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=370183&siteId=1
Recomendado
Clasificación