我已经为我的应用实现了正常关机,并且正在进行测试以确保它按预期运行。控制台上显示的最后一条消息应该是“完成!”。然而事实并非如此。
@Service
public class MyClass {
private boolean keepRunning = true;
@Async
public void myMethod(){
do {
try {
System.out.println("Start");
Thread.sleep(10000);
System.out.println("Done!");
}catch (Exception e){
logger.error(e.getLocalizedMessage());
}
} while(keepRunning);
}
@PreDestroy
void stop() {
System.out.println("Shutdown called!");
this.keepRunning = false;
}
}
我还添加到了server.shutdown=graceful
我的 application.properties 文件中
这是结束应用程序时控制台的完整输出
Start
2024-11-09T12:58:52.932-05:00 INFO 7374 --- [myapp] [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2024-11-09T12:58:52.935-05:00 INFO 7374 --- [myapp] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
Shutdown called!
Process finished with exit code 1
进程不是应该等待循环完成吗?如果不是,我是否可以等待循环完成然后再关闭应用程序?
编辑:
实现如下所示的自定义 taskExecutor 之后
@Bean(name = "test")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("test-");
executor.initialize();
return executor;
}
我还给它添加了“test-”的名称前缀,以确保该方法正在使用它。我还对方法进行了更改
@Async("test")
public void myMethod(){
do {
try {
System.out.println("Start " + Thread.currentThread().getName());
Thread.sleep(10000);
System.out.println("Done!");
}catch (Exception e){
logger.error(e.getLocalizedMessage());
}
} while(keepRunning);
}
应用程序在打印“完成!”消息之前仍会结束。
Start test-1
2024-11-09T14:23:18.132-05:00 INFO 14449 --- [myapp] [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2024-11-09T14:23:18.137-05:00 INFO 14449 --- [myapp] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
Shutdown called!
您需要设置一个超时时间来等待当前线程完成。
添加以下属性:
如果 IDE 未发送正确的 SIGTERM 信号,则可能无法正常使用 IDE 的正常关闭功能。有关详细信息,请参阅 IDE 的文档。
对于关闭调用,您可以添加执行器:
构建.gradle:
为执行器添加以下属性:
您需要设置shutdown.enable才能从执行器获取关闭端点
调用 POST 方法后:http://{HOST}:{PORT}/{CONTEXT_PATH}/actuator/shutdown
您将收到如下回复:
如此处所述,为了防止中断异步正在运行的任务,您需要指定 bean
TaskExecutor
来等待任务完成(使用`setWaitForTasksToCompleteOnShutdown)方法: