在启动生命周期中优雅地退出 quarkus
Gracefully exiting quarkus during startup lifecycle
我想弄清楚在 quarkus 中应用程序启动期间应该如何优雅地失败。
- 我尝试将其添加到应用程序启动代码中。如果我 运行 其中一个单元测试,现在不会调用它。只有在我直接启动应用程序时才会调用它。我希望 return 一个非零值来反对抛出异常。这可能是推荐的方法。我不确定。
public class MyApp implements QuarkusApplication {
@Override
public int run(String... args) throws Exception {
System.out.println("Do startup logic here");
Quarkus.waitForExit();
return 0;
}
- 我还尝试从 onStart 生命周期事件中引发异常。但似乎 quarkus 一直在继续执行
void onStart(@Observes StartupEvent ev) {
LOGGER.info("The application is starting...");
}
void onStop(@Observes ShutdownEvent ev) {
LOGGER.info("The application is stopping...");
}
我不确定这是功能请求还是错误,或者我遗漏了什么,这是正常行为。
编辑1:
明确一点:
@Startup
@ApplicationScoped
public class StarterBean {
private static final Logger LOGGER = Logger.getLogger("");
public StarterBean() {
throw new RuntimeException("failed misrably");
}
}
当我 运行 使用“./gradlew quarkusDev` 时,我在控制台中看到异常,但该应用程序从未存在。我认为它应该存在。它确实在单元测试期间退出并且正确失败。我尝试在 onStart 中移动异常,但这也没有帮助。我还尝试了 Startup、ApplicationScoped 或两者的组合
编辑 2:
我通过构建 uber jar 并 运行 对其进行了测试。引发异常会退出应用程序。同样可以想象,当 运行 在 docker 容器中时,应用程序也会退出。我很困惑为什么 gradle 任务从来不存在。所以为此我想我会接受答案。非常感谢您的帮助!
我不确定这里是否有满足所有要求的 nice 答案(如果我错了,很高兴得到纠正。)不确定你到底想做什么实现,但有一些可能值得探索的选项:
Quarkus.asyncExit(code)
在您的 run()
方法中将允许您正常退出,但这不会被单元测试调用。
- 您可以在启动时初始化一个在其构造函数中抛出异常的 bean(用
@Startup
注释),但这不是特别优雅并且不会让您控制状态代码。然而,它似乎 return -1,所以它至少满足非零退出代码的标准。 (遗憾的是 Quarkus.asyncExit(code)
似乎不适用于单元测试,即使它是在测试开始之前的 bean 初始化中执行的。)
- 同上,但是你可以在bean构造函数中调用
System.exit()
。这使您可以控制退出代码,但这是最不干净的方法,它只是将 VM 拉走而没有任何优雅的清理机会。
编辑:刚刚从 zulipchat 线程看到了这个,它添加了一些必要的上下文:
I need to be able to bail out during startup if i see certain conditions (for example missing env variables or whatever) how am i supposed to do it ?
在这种情况下,我可能会声明一个 @Startup
bean(或多个 bean)以基于这些环境变量进行初始化,并确保这些 bean 的构造函数在条件不正确时抛出有意义的异常(缺少 env 变量、损坏的 env 变量等)这有几个优点:
- 您可以将适当的启动检查分成不同的 bean,强制分离责任;
- 您有有意义的信息可以在日志中进行分析和操作;
- 如果由于抛出该异常而出现错误,您可以使用非零退出代码有意义地停止,从而允许容器运行状况检查系统报告节点已严重死亡。
我想弄清楚在 quarkus 中应用程序启动期间应该如何优雅地失败。
- 我尝试将其添加到应用程序启动代码中。如果我 运行 其中一个单元测试,现在不会调用它。只有在我直接启动应用程序时才会调用它。我希望 return 一个非零值来反对抛出异常。这可能是推荐的方法。我不确定。
public class MyApp implements QuarkusApplication {
@Override
public int run(String... args) throws Exception {
System.out.println("Do startup logic here");
Quarkus.waitForExit();
return 0;
}
- 我还尝试从 onStart 生命周期事件中引发异常。但似乎 quarkus 一直在继续执行
void onStart(@Observes StartupEvent ev) {
LOGGER.info("The application is starting...");
}
void onStop(@Observes ShutdownEvent ev) {
LOGGER.info("The application is stopping...");
}
我不确定这是功能请求还是错误,或者我遗漏了什么,这是正常行为。
编辑1: 明确一点:
@Startup
@ApplicationScoped
public class StarterBean {
private static final Logger LOGGER = Logger.getLogger("");
public StarterBean() {
throw new RuntimeException("failed misrably");
}
}
当我 运行 使用“./gradlew quarkusDev` 时,我在控制台中看到异常,但该应用程序从未存在。我认为它应该存在。它确实在单元测试期间退出并且正确失败。我尝试在 onStart 中移动异常,但这也没有帮助。我还尝试了 Startup、ApplicationScoped 或两者的组合
编辑 2:
我通过构建 uber jar 并 运行 对其进行了测试。引发异常会退出应用程序。同样可以想象,当 运行 在 docker 容器中时,应用程序也会退出。我很困惑为什么 gradle 任务从来不存在。所以为此我想我会接受答案。非常感谢您的帮助!
我不确定这里是否有满足所有要求的 nice 答案(如果我错了,很高兴得到纠正。)不确定你到底想做什么实现,但有一些可能值得探索的选项:
Quarkus.asyncExit(code)
在您的run()
方法中将允许您正常退出,但这不会被单元测试调用。- 您可以在启动时初始化一个在其构造函数中抛出异常的 bean(用
@Startup
注释),但这不是特别优雅并且不会让您控制状态代码。然而,它似乎 return -1,所以它至少满足非零退出代码的标准。 (遗憾的是Quarkus.asyncExit(code)
似乎不适用于单元测试,即使它是在测试开始之前的 bean 初始化中执行的。) - 同上,但是你可以在bean构造函数中调用
System.exit()
。这使您可以控制退出代码,但这是最不干净的方法,它只是将 VM 拉走而没有任何优雅的清理机会。
编辑:刚刚从 zulipchat 线程看到了这个,它添加了一些必要的上下文:
I need to be able to bail out during startup if i see certain conditions (for example missing env variables or whatever) how am i supposed to do it ?
在这种情况下,我可能会声明一个 @Startup
bean(或多个 bean)以基于这些环境变量进行初始化,并确保这些 bean 的构造函数在条件不正确时抛出有意义的异常(缺少 env 变量、损坏的 env 变量等)这有几个优点:
- 您可以将适当的启动检查分成不同的 bean,强制分离责任;
- 您有有意义的信息可以在日志中进行分析和操作;
- 如果由于抛出该异常而出现错误,您可以使用非零退出代码有意义地停止,从而允许容器运行状况检查系统报告节点已严重死亡。