Java 关闭Spring boot应用程序时不允许新的传入连接,但会突然退出

Java 关闭Spring boot应用程序时不允许新的传入连接,但会突然退出,java,spring,spring-boot,model-view-controller,Java,Spring,Spring Boot,Model View Controller,我有一个spring boot应用程序,它创建了一个线程,在调用SpringApplication.exit()之前监视空闲时间,以便在长时间处于空闲状态时终止应用程序。。我有一个restcontroller类,它提供web请求 问题是,即使在调用SpringApplication.exit()之后,控制器似乎也会在应用程序退出之前的一小段时间内接受传入的连接。当控制器接受新的传入连接时,这会导致客户端突然终止,然后先前对SpringApplication.exit()的调用生效并使应用程序退出

我有一个spring boot应用程序,它创建了一个线程,在调用SpringApplication.exit()之前监视空闲时间,以便在长时间处于空闲状态时终止应用程序。。我有一个restcontroller类,它提供web请求

问题是,即使在调用SpringApplication.exit()之后,控制器似乎也会在应用程序退出之前的一小段时间内接受传入的连接。当控制器接受新的传入连接时,这会导致客户端突然终止,然后先前对SpringApplication.exit()的调用生效并使应用程序退出

//伪码

@RestController
public class AppController {

  @PostMapping("/testproc")
  public ExitStatus process(@RequestBody Job testJob) {
    logger.info("Job batch Id passed: {}", testJob.batchId);
    //do processing
    if(shutdownFlag) {
        //report error to client
    } else {
        //do regular processing
    }
  }
}

@SpringBootApplication
public class MyApplication {

  public static void main(String[] args) {
    ctx = SpringApplication.run(MyApplication.class, args);
    Thread shutdownThread = new Thread(new Runnable() {
                  //check for some condition
                  if(shutdownFlag) {
                       logger.info("Exiting");
                       SpringApplication.exit(ctx, () -> 0);
                       return;
                  }
             });

    shutdownThread.start();
  }
}
生成的日志:

2019-03-23 02:02:46.439信息13484---[Thread-10]c.i.e.newgenv1.svc.MyApplication:退出 2019-03-23 02:02:46.441信息13484---[Thread-10]配置ServletWebServerApplicationContext:关闭org.springframework.boot.web.servlet.context。AnnotationConfigServletWebServerApplicationContext@6660a289:启动日期[2019年3月23日星期六02:02:29];上下文层次结构的根 2019-03-23 02:02:46.509信息13484---[nio-8081-exec-2]o.s.web.servlet.DispatcherServlet:FrameworkServlet“DispatcherServlet”:初始化已开始 2019-03-23 02:02:46.665信息13484---[nio-8081-exec-2]o.s.web.servlet.DispatcherServlet:FrameworkServlet“DispatcherServlet”:初始化在156毫秒内完成 2019-03-23 02:02:47.559信息13484---[nio-8081-exec-2]c.i.etl.newgenv1.svc.AppController:传递的作业批次Id:23 2019-03-23 02:02:53.828信息13484---[Thread-10]o.s.j.e.a.AnnotationMBeanExporter:在关机时注销JMX暴露的bean 请注意记录的线路。。关机线程生成的“退出”行发生在控制器拾取连接并打印批处理id之前

我需要停止控制器拾取新连接,或者在这些时间向客户端报告错误代码。但问题是,控制器接收到连接,但在报告错误之前,应用程序退出

我甚至尝试了以下列出的优雅关机逻辑:


但仍然没有帮助。

您可以添加一个拦截器,它将检查是否启动了关机。如果没有,则流将继续正常执行,否则应丢弃请求并发送正确的响应。

Spring无法自动管理您创建的原始线程的生命周期。如果您想让spring管理它,请使用springs ExecutorService,它应该自动配置。请看这里的示例:我不想管理线程的生命周期。我想确保在调用SpringApplication.exit时,控制器不再接受新连接。。这就是我面临的问题是的,没错。你不想自己管理生命周期,这就是为什么你想使用Spring ExecutorService,所以Spring为你管理它。当进程本身退出时,我如何拦截和发送响应?进程尚未完全退出,这就是为什么控制器仍在执行。因此,您可以添加一个拦截器,该拦截器将拦截所有请求URL(*),并在其“preHandle”中检查“shutdownFlag”是否设置为true。如果为true,则填充正确的错误消息和响应代码,并向客户端抛出错误。事实上,iam在控制器内检查关机标志并发送错误响应,而不是特定的拦截器。。我检测到控制器内的关机标志并发送。。但问题是,当控制器接受连接时,进程正在运行,但在控制器可以发送响应之前,进程就退出了。。你能给我一个我可以试试的示例代码吗 2019-03-23 02:02:46.439 INFO 13484 --- [ Thread-10] c.i.e.newgenv1.svc.MyApplication : Exiting 2019-03-23 02:02:46.441 INFO 13484 --- [ Thread-10] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6660a289: startup date [Sat Mar 23 02:02:29 IST 2019]; root of context hierarchy 2019-03-23 02:02:46.509 INFO 13484 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2019-03-23 02:02:46.665 INFO 13484 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 156 ms 2019-03-23 02:02:47.559 INFO 13484 --- [nio-8081-exec-2] c.i.etl.newgenv1.svc.AppController : Job batch Id passed: 23 2019-03-23 02:02:53.828 INFO 13484 --- [ Thread-10] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown