[spring-projects/spring-boot]关闭时 LoggingSystem 无法记录 DisposableBean#destroy 调用

2024-06-26 17 views
4

我在 Spring Tool Suite (Version: 3.9.7.RELEASE) 中运行 Spring Boot 2.5.0 应用程序。通过 STS 的“停止”按钮停止该应用程序,我发现destroyDisposableBean 未执行。如果我返回到 Spring Boot 2.4.x 或 2.3.x,该功能将正常。

这是 Spring Tool Suite 的问题还是延迟?请参阅我的代码,在 2.5.0 中,“正在关闭...”记录器不会打印...

public class MyOperation implements DisposableBean {

    private static final Logger LOG = LoggerFactory.getLogger(MyOperation.class);

    @Override
    public void destroy() throws Exception {
        LOG.info("Shutting down...");
    }

}

回答

9

@HaojunRen 很难根据你到目前为止的描述找出问题所在。为了帮助我们,你可以使用debugset 启动应用程序并在关机时粘贴日志。请对具有相同 STS 版本的 2.4.x 和 2.5.x 执行此操作,以便我们可以比较正在发生的事情。

4

是的,它使用相同的 STS。在debug模式下,它不会转到调试点。我会尝试在 STS 中提供 2 个屏幕截图。我希望​​它能说明问题。非常感谢 图片 图片

1

@HaojunRen 恐怕截图没什么用。我们需要的是两个应用程序的日志,以便找出差异或帮助我们追踪问题的东西。

我提到的是debug打开一些调试日志的属性,并不是在谈论使用调试器。

8

是的。目前,我看不出有什么明显的东西可以解释为什么它在 2.4.x 和 2.5.x 中被调用。考虑到还涉及其他库,我们现在需要一个可以重现问题的小样本。您可以将样本作为 zip 文件附加到此问题或将其推送到 GitHub 并共享存储库链接。谢谢。

4

你说的对,小样本没有这个问题。我猜想 Spring Cloud 2020 可能还没有支持 Spring Boot 2.5.0,或者其他未知的库。很难找出原因,因为没有任何异常或错误日志...

多谢

1

@snicoll 看来我找到了问题的根源,请参考图片 图片

  1. 在 Spring Boot 应用程序停止之前,SLF LOG 工作正常
  2. destroy方法DisposeBean已成功触发,因为system.out.println执行成功
  3. 最终的 LOG.info 未被触发...

我担心的是在 DisposeBean 之前,SLF4J LOG 仍然被销毁了?

4

这是否解释了为什么Spring Boot在调试模式下不输出日志?

4

@HaojunRen 感谢您的跟进。重新打开问题没问题,但请提供我要求的示例应用程序。我担心屏幕截图没什么帮助。

这是否解释了为什么Spring Boot在调试模式下不输出日志?

我不明白这一点。如果您唯一关心的是日志语句,那么,是的,可能是日志系统在不同阶段关闭(尽管我没有迹象表明是这种情况)。同样,没有理由相信DisposableBean关闭时不会调用实现。

5

例子.zip

请尝试此示例,调用了“DisposableBean”,但使用 Spring Boot 2.5.0 的 STS 中没有输出日志,但可以在 2.4.x、2.3.x 中输出

4

谢谢。Spring Boot 中发生了一些变化2.5.0,阻止了LoggingSystem早期潜在问题。这对调用没有影响DisposableBean,因此我相应地重命名了该问题。

6

好的,非常感谢

2

使用 Spring Boot 2.5,我们将日志系统更改为始终注册关闭钩子(参见 #25046)。现在的情况是,当应用程序终止时,日志系统和应用程序都会ApplicationContext关闭。这是并行发生的,因此日志系统可能会在一次性 bean 有机会添加日志之前关闭。

5

修复这个问题有点棘手。我在这个分支上有一些内容,但我希望团队中的其他人能够对其进行审查。

它的工作原理是跟踪在弱映射中启动的映射,然后在调用真正的关闭钩子之前ApplicationContexts检查它们。isActive() false