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

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

相关推荐
BingoGo5 分钟前
PHP 集成 FFmpeg 处理音视频处理完整指南
后端·php
还听珊瑚海吗9 分钟前
基于WebSocket和SpringBoot聊天项目ChatterBox测试报告
spring boot·websocket·网络协议
数字人直播12 分钟前
稳了!青否数字人分享3大精细化AI直播搭建方案!
前端·后端
掘金一周24 分钟前
被老板逼出来的“表格生成器”:一个前端的自救之路| 掘金一周 8.21
前端·人工智能·后端
Monly2137 分钟前
RabbitMQ:SpringAMQP Topic Exchange(主题交换机)
spring boot·rabbitmq·java-rabbitmq
SimonKing44 分钟前
开源新锐:SQL玩转搜索引擎?Manticore颠覆你的认知
java·后端·程序员
MaxHua2 小时前
数据库入门指南与实战进阶-Mysql篇
后端
用户4099322502122 小时前
FastAPI的死信队列处理机制:为何你的消息系统需要它?
后端·ai编程·trae
用户4822137167752 小时前
C++——纯虚函数、抽象类
后端
张同学的IT技术日记2 小时前
必看!用示例代码学 C++ 基础入门,快速掌握基础知识,高效提升编程能力
后端