我是怎么把应用启动时间从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造成的瓶颈已经消失。

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

相关推荐
来自宇宙的曹先生1 分钟前
用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
spring boot·redis·后端
expect7g22 分钟前
Flink-Checkpoint-1.源码流程
后端·flink
00后程序员29 分钟前
Fiddler中文版如何提升API调试效率:本地化优势与开发者实战体验汇总
后端
用户8122199367221 小时前
C# .Net Core零基础从入门到精通实战教程全集【190课】
后端
bobz9651 小时前
FROM scratch: docker 构建方式分析
后端
lzzy_lx_20891 小时前
Spring Boot登录认证实现学习心得:从皮肤信息系统项目中学到的经验
java·spring boot·后端
小七mod1 小时前
【Spring】Java SPI机制及Spring Boot使用实例
java·spring boot·spring·spi·双亲委派
前端付豪2 小时前
21、用 Python + Pillow 实现「朋友圈海报图生成器」📸(图文合成 + 多模板 + 自动换行)
后端·python
MaxHua2 小时前
以 AI 之力重塑 Java 研发,解锁高效开发新范式
后端