Java应用启动优化
Java应用在启动的时候需要做大量的编译工作,如果应用依赖了Spring,因为其IOC的特性会提前加载运行时所需的各种Bean,随着项目变的复杂,里面的Bean也越来越多...
其中带来一个新的问题就是项目每次启动非常慢: 见过比较慢的应用启动一次要30分钟,一个下午发布几次代码时间就没了。 就算是自己应用,写了两年之后,发现每次启动也需要个5~10分钟的时间,这种启动速度会极大的降低开发的效率。
如何优化应用的启动时间?
找出最耗时的Bean有哪些
通过Spring的BeanPostProcessor接口可以统计到每个Bean的初始化耗时时长。
@Service @Slf4j public class BeanInitMetrics implements BeanPostProcessor { private Map<String, Long> stats = new HashMap<>(); //private Map<String,Integer> metrics = new HashMap<>(); private List<Metric> metrics = new ArrayList<>(); @Data static class Metric{ public Metric() { } public Metric(String name, Integer value) { this.name = name; this.value = value; this.createDate = new Date(); } private String name; private Integer value; private Date createDate; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { stats.put(beanName, System.currentTimeMillis()); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Long start = stats.get(beanName); if (start != null) { metrics.add(new Metric(beanName, Math.toIntExact(System.currentTimeMillis() - start))); } return bean; } public List<Metric> getMetrics() { metrics.sort((o1, o2) -> { try { return o2.getValue() - o1.getValue(); }catch (Exception e){ return 0; } }); log.info("metrics {}", JSON.toJSONString(metrics)); return UnmodifiableList.unmodifiableList(metrics); } }
![](https://uploadfiles.nowcoder.com/files/20220912/882557124_1662946888200/10995913-fb236547cd9c2dd5.png)
分类优化
中间件优化
- 配置一些中间件的超时时长;开发环境、预发环境超时时长设置短一点;
- 考虑升级一些中间件版本:Tomcat,Spring,JDK等
- 中间件一般属于应用的最底层,判断能否进行并行优化;
StackOverFlow上有人给出了一些参考方式:stackoverflow.com/questions/6…
应用层历史包袱
- Maven的分析有哪些包没有被使用,排除掉这些Jar包:maven.apache.org/shared/mave…
- 代码中一些已经迁移到其他应用中的业务,有些已经迁移了但是还遗留了大量的代码,这种在开发环境下都可以先进行排除
应用层其它优化
- 一些Bean考虑是否可以懒加载
- 一些引入的重量级Bean预加载范围过大,设置下业务范围; 有些富客户端的Client在启动的时候会预加载需要的配置,有些配置量非常的大,一个Bean的启动都需要几分钟的时间,对这种Client考虑可以配置范围预加载,只提前加载自己业务下的配置。
其它优化
- 使用热部署...
- 不要依赖Snapshot包
- 编译优化:Maven并行编译
实践结果
有效的动作:
1、真正导致应用启动耗时久的主要是前几十个Bean,主要原因一般是预加载内容多,或者线程池,或者IO。
2、容器支持一些配置参数,开启异步,禁止一些启动分析等。
项目从5~10分钟的启动时间缩短到3分钟启动;以上是启动优化的一点经验
#Java##程序员#