如何让Quarkus应用执行完任务后自动退出?
Quarkus Scala应用执行完任务后无法自动退出的解决方法
问题场景
我们团队基于Quarkus框架开发任务型应用,要求任务执行完毕后自动退出。用Scala实现了继承QuarkusApplication的EMRExecutionMonitor,主入口通过Quarkus.run(classOf[EMRExecutionMonitor], args: _*)启动应用。但运行打包后的Jar包(java -jar quarkus-run.jar)时,调用Quarkus.asyncExit(0)后程序仍无法自动退出,必须手动按Ctrl+C终止。
原代码如下:
class EMRExecutionMonitor extends QuarkusApplication { private val logger = LoggerFactory.getLogger(this.getClass) override def run(args: String*): Int = { logger.info("start EMR execution monitoring job") Quarkus.waitForExit() Quarkus.asyncExit(0) 0 } }
核心原因
代码中调用的Quarkus.waitForExit()方法会阻塞当前线程,等待外部终止信号(比如Ctrl+C)才会继续执行后续代码。这就导致后面的Quarkus.asyncExit(0)根本没有执行机会,程序一直处于阻塞等待状态,无法自动退出。
解决方案
- 移除
Quarkus.waitForExit()调用:该方法适用于需要长期运行、等待外部触发退出的服务型应用,不适合任务执行完就退出的场景。 - 确保任务逻辑执行完毕后,调用
Quarkus.asyncExit(0)触发退出,或者直接返回退出码(Quarkus会自动处理应用终止)。
修正后的基础代码
class EMRExecutionMonitor extends QuarkusApplication { private val logger = LoggerFactory.getLogger(this.getClass) override def run(args: String*): Int = { logger.info("start EMR execution monitoring job") // 这里添加你的EMR监控任务执行逻辑 // 比如:executeEMRMonitoringTasks() // 任务执行完成后触发退出 Quarkus.asyncExit(0) 0 } }
处理异步任务场景
如果你的EMR监控任务是异步执行的,需要先等待异步任务完成后再触发退出,避免任务未执行完毕程序就终止:
import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit class EMRExecutionMonitor extends QuarkusApplication { private val logger = LoggerFactory.getLogger(this.getClass) override def run(args: String*): Int = { logger.info("start EMR execution monitoring job") // 封装异步执行的任务逻辑 val monitoringTask = CompletableFuture.runAsync(() => { logger.info("Executing EMR monitoring task...") try { // 模拟任务耗时,替换为实际业务逻辑 TimeUnit.SECONDS.sleep(5) } catch { case e: InterruptedException => Thread.currentThread().interrupt() } logger.info("EMR monitoring task completed") }) // 等待异步任务执行完成 monitoringTask.get() // 任务结束后退出应用 Quarkus.asyncExit(0) 0 } }
验证方式
重新打包Jar包,执行java -jar quarkus-run.jar,观察日志输出:任务执行完成后,程序会自动终止,无需手动输入Ctrl+C。
内容的提问来源于stack exchange,提问作者Weever
相关产品推荐
相关产品推荐

