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

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

相关推荐
橘猫云计算机设计2 分钟前
基于Java的班级事务管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·开发语言·数据库·spring boot·微信小程序·小程序·毕业设计
计算机-秋大田11 分钟前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
熬了夜的程序员16 分钟前
Go 语言封装邮件发送功能
开发语言·后端·golang·log4j
uhakadotcom17 分钟前
PostgreSQL 行级安全性(RLS)简介
后端·面试·github
小马爱打代码40 分钟前
Spring Boot - 动态编译 Java 类并实现热加载
spring boot·后端
网络风云1 小时前
Flask(二)项目结构与环境配置
后端·python·flask
小杨4042 小时前
架构系列二十三(全面理解IO)
java·后端·架构
uhakadotcom2 小时前
Tableau入门:数据可视化的强大工具
后端·面试·github
demonlg01122 小时前
Go 语言 fmt 模块的完整方法详解及示例
开发语言·后端·golang
程序员鱼皮2 小时前
2025 年最全Java面试题 ,热门高频200 题+答案汇总!
java·后端·面试