Spring Boot 应用程序 - 启动时间与“mvn spring-boot:run”和“java -jar”的差异

Posted

技术标签:

【中文标题】Spring Boot 应用程序 - 启动时间与“mvn spring-boot:run”和“java -jar”的差异【英文标题】:Spring Boot application - difference in startup time with "mvn spring-boot:run" and "java -jar" 【发布时间】:2018-04-20 23:48:12 【问题描述】:

我注意到我的 Spring Boot 应用程序在使用 Maven 和 jar 启动时的启动时间存在很大差异。例如:

mvn spring-boot:run - 5 秒 java -jar myapp.jar - 25 秒

启动 jar 文件需要大约 5 倍的时间。为什么会这样?使用 Maven 和 jar 启动应用程序时,后台发生了什么?加载的东西不同吗?是否可以在 Maven 使用的时间内启动 jar 文件?

【问题讨论】:

你是如何测量时间的? 我在SpringApplication.run(MySpringBootApplication.class, args); 之前和之后添加了new Date() 之后我记录了差异。 在使用<fork>true</fork> for maven 和java -jar myapp.jar 时,您能否测量每个进程存在的时间? 这个配置好像对启动时间影响不大。 Maven 使用<fork>true</fork><fork>false</fork> 所花费的时间几乎相同。 <fork>true</fork> 甚至快了 0.2 秒。这有任何意义吗?而java -jar myapp.jar 仍然需要大约 4-5 倍的时间。 【参考方案1】:

这种差异可能是由于 spring-boot:run 实际上是在 Maven JVM 中运行 Spring Boot 应用程序(除非您明确设置 fork 参数),当它在 Maven JVM 中运行时,它实际上是作为新线程不是进程。创建线程比进程快得多。

但是java -jar 命令将创建一个 OS 进程,进程创建附加了一些步骤,例如请求进程 ID、分配内存等。除此之外,myapp.jar 将需要提取,而 JVM 将没有任何优化,因为它将第一次读取从 jar 文件中提取的.class。基本上是一个需要时间的冷启动。

可以看Maven Spring Boot Pluginhere的源码

【讨论】:

感谢您回答我的问题。我在pom.xml 中使用<fork>true</fork><fork>false</fork> 进行了尝试,但结果是一样的——我仍然需要5 秒钟的Maven。我还解压了myapp.jar 并使用了java -cp .\myapp org.springframework.boot.loader.JarLauncher,但结果是一样的——25 秒。我还能尝试什么? 我很难相信你的回答。进程创建不需要几秒钟,最多需要几毫秒,可能是微秒。从 maven 运行并没有改变必须加载类并且还没有被 jvm 优化的事实。 我在启动时有一些数据库初始化,这就是为什么这个过程很慢。但这并没有改变使用 Maven 启动速度更快的事实。当我禁用数据库的初始化时,我需要 2 秒的时间来使用 Maven(<fork>true</fork><fork>false</fork> 无关紧要)。启动 jar 大约需要 7 秒。它仍然慢了 3 倍以上。 所以,现在我创建了一个简单的“Hello World”项目(Spring Boot + Thymeleaf)。我有以下启动时间: Maven(通过 Eclipse 运行为...):1.5 秒; mvn spring-boot:run: 2 秒; java -jar:4.5 秒。我也用fork真假测试过,这个对时间没有任何影响。我做错了吗?

以上是关于Spring Boot 应用程序 - 启动时间与“mvn spring-boot:run”和“java -jar”的差异的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot的应用启动与关闭

Spring Boot 和 Hibernate:即使与数据库的连接不可用也启动应用程序

在我的 spring-boot 应用程序启动之前,我如何等待数据库容器启动

Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)

Spring Boot的启动与调用

Flyway Spring Boot应用程序在启动时不应用插入脚本