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

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

相关推荐
奋进的芋圆9 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
武藤一雄9 小时前
C# 关于多线程如何实现需要注意的问题(持续更新)
windows·后端·microsoft·c#·.net·.netcore·死锁
程序新视界10 小时前
为什么不建议基于Multi-Agent来构建Agent工程?
人工智能·后端·agent
AC赳赳老秦11 小时前
Python 爬虫进阶:DeepSeek 优化反爬策略与动态数据解析逻辑
开发语言·hadoop·spring boot·爬虫·python·postgresql·deepseek
Victor35611 小时前
Hibernate(29)什么是Hibernate的连接池?
后端
Victor35611 小时前
Hibernate(30)Hibernate的Named Query是什么?
后端
源代码•宸11 小时前
GoLang八股(Go语言基础)
开发语言·后端·golang·map·defer·recover·panic
czlczl2002092511 小时前
OAuth 2.0 解析:后端开发者视角的原理与流程讲解
java·spring boot·后端
颜淡慕潇11 小时前
Spring Boot 3.3.x、3.4.x、3.5.x 深度对比与演进分析
java·后端·架构
布列瑟农的星空11 小时前
WebAssembly入门(一)——Emscripten
前端·后端