我是怎么把应用启动时间从1000秒优化到100秒的

背景

最近在本地启动项目,发现启动时间变得超级慢,以前一会就启动完的项目,现在启动十来分钟还迟迟没能响应。刚开始怀疑是不是最近应用做了哪些改动,增加了耗时的操作,导致启动变得奇慢无比。但是看了测试环境跟生产环境应用的启动时间,发现两个环境的启动时间跟之前无差。合着只有在本地启动才慢(可能想让我接着启动时间好好休息下),但是因实在忍受不了这个启动时间,所以决定看看是啥问题导致的。

项目: springboot + dubbo

本地系统:mac

开发环境:idea + jdk1.8

寻找突破点

应用启动的时候,在初始化各种bean的时候,会在控制台打印日志,但是对着密密麻麻的日志一顿找,看下来也没找到突破口。有点像无头苍蝇一样,没有分析的着力点。想着在springboot启动的各个扩展点加上一些自定义的实现,来看看具体耗时在哪里,但是扩展点多,又不想在应用上做改动(主要是懒),于是便没有用这种方式来定位。

想起之前在优化另一个项目的启动时间时,用了一款挺好用的工具,于是便再去github上把该项目找出来用(顺丰哪有顺手快)。这里也给大家安利一下:github.com/linyimin081...

这个开源项目,主要是用于分析springboot项目的启动耗时的,非常对口。于是按照说明,把release包下载下来解压备用。按项目说明,在idea启动应用时,添加jvm参数:

java 复制代码
-javaagent:解压路径/spring-startup-analyzer/lib/spring-profiler-agent.jar

其他的保持默认,没再单独设置其他启动参数。接着将项目启动,经过漫长的等待,项目启动完成之后控制台会打印:

======= spring-startup-analyzer finished, click http://localhost:8065 to visit details. ======

点击链接访问,就可以看到应用启动耗时及各个bean的初始化时间。

优化前

真是不看不知道,一看就知道。在本地启动应用的时候,耗时居然近1000S

点进去Spring Bean Initialization查看bean初始化耗时,可以看到有些bean耗时很高

然而去到对应的类的代码去看,也没有特殊的耗时操作。为了更加直观的看出哪里有耗时瓶颈,于是打开最下面的火焰图:

通过火焰图可以看到,java.net.InetAddress.getLocalHost耗时比较高。想着会不会跟本地的一些host配置有关导致getLocalHost耗时高。于是快速写个demo验证下:

java 复制代码
public class Test {
    public static void main(String[] args) throws UnknownHostException {
        long start = System.currentTimeMillis();
        InetAddress localHost = InetAddress.getLocalHost();
        long end = System.currentTimeMillis();
        System.out.println("getLocalHost time cost: " + (end - start));
        start = System.currentTimeMillis();
        String hostName = localHost.getHostName();
        end = System.currentTimeMillis();
        System.out.println("getHostName time cost: " + (end - start));
        System.out.println(hostName);
    }
}

程序打印结果:

getLocalHost time cost: 5030

getHostName time cost: 12

wiggindeMacBook-Pro.local

尝试解决

单是getLocalHost就用了5S,那程序里各种网络连接或多或少都会用到getLocalHost,那这样算下来整个耗时就会被拉的很长。于是上网查了下,修改了本地host配置,将我电脑的hostName配置进去

java 复制代码
127.0.0.1       localhost wiggindeMacBook-Pro.local

然后刷新下dns

java 复制代码
sudo killall -HUP mDNSResponder

完成上述操作之后再运行demo程序,得到的输出结果如下

getLocalHost time cost: 23

getHostName time cost: 0

wiggindeMacBook-Pro.local

可以看到 getLocalHost由原来的5s锐减成23毫米,看了配置是生效了。于是重新启动项目:

可以看到优化后,启动时间变为97秒

再次打开火焰图可看到,java.net.InetAddress.getLocalHost造成的瓶颈已经消失。

至此,应用本地启动时间恢复正常,我的战术性休息时间也没了

相关推荐
wb043072019 小时前
使用 Java 开发 MCP 服务并发布到 Maven 中央仓库完整指南
java·开发语言·spring boot·ai·maven
nbwenren10 小时前
Springboot中SLF4J详解
java·spring boot·后端
helx8211 小时前
SpringBoot中自定义Starter
java·spring boot·后端
rleS IONS12 小时前
SpringBoot获取bean的几种方式
java·spring boot·后端
lifewange12 小时前
Go语言-开源编程语言
开发语言·后端·golang
白毛大侠12 小时前
深入理解 Go:用户态和内核态
开发语言·后端·golang
R***z10113 小时前
Spring Boot 整合 MyBatis 与 PostgreSQL 实战指南
spring boot·postgresql·mybatis
王码码203513 小时前
Go语言中的数据库操作:从sqlx到ORM
后端·golang·go·接口
星辰_mya13 小时前
雪花算法和时区的关系
数据库·后端·面试·架构师
赵丙双14 小时前
spring boot AutoConfiguration.replacements 文件的作用
java·spring boot