【问题标题】:How do I properly restart a Spring boot application?如何正确重启 Spring Boot 应用程序?
【发布时间】:2019-06-17 21:58:09
【问题描述】:

我正在使用来自here 的代码重新启动我的 Spring Boot 应用程序:

Thread restartThread = new Thread(() -> restartEndpoint.restart());
restartThread.setDaemon(false);
restartThread.start();

但是,重新启动的应用程序无法创建 bean,最终是由于在尝试调度 @Scheduled-annotated 方法时抛出了 RejectedExecutionException

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean' defined in URL [insert-path-here]: Initializetion of bean failed; nested exception is org.springframework.core.TaskRejectedException: Executor [java.util.concurrent.ScheduledThreadPoolExecutor@284a4a89[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 21508]] did not accept task: my.package.MyBean.scheduledMethod

doRestart() 调用之后的日志表明 ExecutorService taskScheduler 正在关闭,这可以解释为什么会发生这种情况。我不完全确定的是为什么没有重新创建 ExecutorService。 令人尴尬的是,事实证明 taskScheduler 是我的应用程序定义的 bean 并且没有注释 @RefreshScope。现在我得到的错误是

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'anotherBean' definen in URL[...]: Unsatisfied dependency expressed through constructor parameter 0 ... nested exception is  java.lang.IllegalStateException: org.springframework.boot.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a95076c has been closed already

在日志中向上滚动一点显示有一个 ApplicationContextException 抛出,堆栈跟踪包含 doRestart

org.springframework.ApplicationContextException: Unable to start web server; nested exception is java.lang.IllegalStateException: Filters cannot be added to context [/myapp] as the context has been initialized
    at org.springframework.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:157)
    ...
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
    at org.springframework.cloud.context.restart.RestartEndpoint(RestartEndpoint.java:160)
    at my.package.MyBean.lambda$doThingAndRestart$2 (MyBean.java: 118)

谷歌搜索此错误似乎导致single page 不相关,尽管我确实注意到此应用程序也在 tomcat 上运行。

我怀疑这与应用程序创建了错误类型的应用程序上下文有关,即AnnotationConfigServletWebServerApplicationContext,它没有扩展AbstractRefreshableAplicationContext

我需要做些什么来消除这个错误?

当我只从堆栈跟踪中复制单行时,请多多包涵。我在两台计算机上设置,所以我不能复制和粘贴,也不允许将日志移动到连接到 Internet 的计算机上。

【问题讨论】:

    标签: java spring-boot tomcat


    【解决方案1】:

    原来RestartEndpoint 只适用于 Spring 的内部 Tomcat,而不是外部的。因此,需要另一种解决方案。我发现的是

    • 当配置文件被覆盖时,使用 Tomcat 的WatchedResource 重新部署服务器。这样做的缺点是在维护 doThingAndRestart 功能时需要维护 Tomcat 配置。
    • 使用 Tomcat 的Manager App。我注意到 reload 请求会阻塞,直到应用完成重新加载,这会溢出堆空间。
    • 使用 Spring 的RefreshEndpoint。无论出于何种原因,这都没有刷新数据源。

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2018-12-30
      • 2020-03-30
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多