Ich habe mehrere Methoden mit Anmerkungen versehen @Scheduled(fixedDelay=10000)
.
Im Anwendungskontext habe ich dieses annotationsgesteuerte Setup:
<task:annotation-driven />
Das Problem ist, dass einige der Methodenausführungen manchmal um Sekunden und sogar Minuten verzögert werden.
Ich gehe davon aus, dass selbst wenn eine Methode eine Weile braucht, um die Ausführung abzuschließen, die anderen Methoden immer noch ausgeführt werden. Ich verstehe die Verzögerung also nicht.
Gibt es eine Möglichkeit, die Verzögerung zu verringern oder sogar zu beseitigen?
quelle
Executor
Schnittstelle keineshutdown()
Methode hat, ist es wahrscheinlich besser, sieExecutorService
als Rückgabetyp zu verwenden, um die Bean-Definition korrekt zu machen. Oder wird Spring zur Laufzeit den tatsächlichen Bean-Typ ermitteln?<task:scheduler id="taskScheduler" pool-size="5"/>
In der Dokumentation zur Zeitplanung heißt es:
Wenn Sie also viele geplante Aufgaben haben, sollten Sie den Scheduler wie in der Dokumentation erläutert so konfigurieren, dass er einen Pool mit mehr Threads hat, um sicherzustellen, dass eine lange Aufgabe nicht alle anderen verzögert.
quelle
task:scheduler
einenpool-size
Parameter. Gilt dies für die@Scheduled
Annotation, die keine poolbezogenen Parameter enthält?Eine mit Annotationen versehene Methode
@Scheduled
soll zu einem bestimmten Zeitpunkt separat auf einem anderen Thread ausgeführt werden.Wenn Sie
TaskScheduler
in Ihrer Konfiguration keine angegeben haben , wird Spring verwendetDies gibt einen zurück
ScheduledExecutorService
, der auf einem einzelnen Thread ausgeführt wird. Wenn Sie über mehrere@Scheduled
Methoden verfügen , müssen diese, obwohl sie geplant sind, jeweils warten, bis der Thread die Ausführung der vorherigen Aufgabe abgeschlossen hat. Es kann immer wieder zu Verzögerungen kommen, da sich die Warteschlange schneller füllt als sie sich leert.Stellen Sie sicher, dass Sie Ihre Planungsumgebung mit einer geeigneten Anzahl von Threads konfigurieren.
quelle
@Scheduled
(und@EnableScheduling
) wird durch Registrierung von a behandeltScheduledAnnotationBeanPostProcessor
. Dieser Postprozessor verwendet einen,ScheduledTaskRegistrar
der standardmäßig diesen Single-Thread verwendetScheduledExecutorService
.UPDATE 2019
Es gibt auch eine Eigenschaft, die Sie in Ihrer Anwendungseigenschaftendatei festlegen können, um die Poolgröße zu erhöhen:
spring.task.scheduling.pool.size=10
Scheint seit Spring Boot 2.1.0 da zu sein.
quelle
Sie können verwenden:
@Bean() public ThreadPoolTaskScheduler taskScheduler(){ ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(2); return taskScheduler; }
quelle
taskScheduler.initialize();
bevor Sie Ihre Instanz vontaskScheduler
Die Annotation @EnableScheduling enthält die wichtigsten Informationen und deren Lösung:
@Configuration @EnableScheduling public class AppConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } }
(Betonung hinzugefügt)
quelle
Fügen Sie mithilfe der XML-Datei die folgenden Zeilen hinzu.
<task:scheduler id="taskScheduler" pool-size="15" /> <task:scheduled-tasks scheduler="taskScheduler" > .... </task:scheduled-tasks>
quelle
Standardfeder mit einem einzelnen Thread für die Zeitplanaufgabe. Sie können @Configuration für Klassenimplementierungen verwenden, die SchedulingConfigurer implementieren. Referenz:
https://crmepham.github.io/spring-boot-multi-thread-scheduling/
quelle