使用Akka HTTP的Scala应用在Future完成后仍不退出如何解决
问题原因
Akka Http底层依赖Akka ActorSystem以及配套的线程池、连接池资源,这些资源默认启动的都是非守护线程,只要这类线程没有被主动关闭,JVM就会持续保持运行状态,不会自动退出。
你代码中调用Http().singleRequest(req)时,Akka Http会自动初始化默认的ActorSystem、Http连接池、调度线程池等资源,这些资源不会因为请求逻辑执行完成就自动销毁,所以会导致主进程无法退出。
解决方案
在所有业务逻辑执行完成后,主动关闭ActorSystem释放所有关联资源即可,修改后的参考代码如下:
import akka.actor.ActorSystem import scala.concurrent.Await import scala.concurrent.duration.Duration object Main { // 显式声明ActorSystem,方便后续资源管理,避免依赖自动生成的隐式实例 implicit val system: ActorSystem = ActorSystem("http-client-system") def main(args: Array[String]): Unit = { try { val req = HttpRequest(GET, myURL) val res = Http().singleRequest(req) val resultsFutures = Future { val resultString = Await.result(HttpRequests.unpackResponse(res), Duration.Inf) JsonMethods.parse(resultString).extract[List[Results]] } val results = Await.result(resultsFutures, Duration.Inf) println(results) } finally { // 主动关闭ActorSystem,释放所有线程、连接资源 Await.result(system.terminate(), Duration.Inf) } } }
注意事项
- 如果你没有显式声明ActorSystem,也可以通过
Http().system.terminate()关闭自动生成的默认实例,但更推荐显式声明ActorSystem方便资源管控 - Akka 2.5.x版本关闭ActorSystem后会自动释放关联的Http连接池、调度器等所有资源,无需额外单独关闭Http组件
- 该方案仅适用于单次执行的脚本类任务,生产环境长期运行的服务不要随意关闭ActorSystem
内容的提问来源于stack exchange,提问作者Seb
相关产品推荐
相关产品推荐

