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 和 Hibernate:即使与数据库的连接不可用也启动应用程序
在我的 spring-boot 应用程序启动之前,我如何等待数据库容器启动