-
Notifications
You must be signed in to change notification settings - Fork 131
能力介绍
首先通过项目给出的HTML样例报告来看看此工具提供的分析功能。感兴趣的可以通过下面的链接访问:
把报告内容的细节部分收起来,可以看到如下图所示的内容:
主要包含6部分:
- 启动的统计数据。其中包括:启动时间、Bean的数量、使用/总共的jar包数量、未使用/总共的jar包数量及ClassLoader数量;
- Spring Bean初始化数据,采集了每个Spring Bean初始化时间及其详细内容;
- Bean初始化时间线。通过时间线的方式,清晰地展现了Spring应用启动过程中,各个Bean的顺序关系及时间消耗;
-
方法调用详细信息(可配置)。这里统计了方法的调用时间、总时间开销及每次调用平均时间
- 点开之后,还能看到具体每次调用的时间开销和调用细节:
- 点开之后,还能看到具体每次调用的时间开销和调用细节:
- 启动后未被加载的JAR。列出了所有Spring应用启动后没有使用的jar包,可以有效地帮助清理不需要的依赖,为应用瘦身;
- Spring应用启动过程主线程火焰图。提供更详细的信息用于分析应用启动卡点
提供了生产环境和日常/预发环境两种场景的优化,对于生产环境,提供Spring Bean异步加载工具,将耗时的Bean初始化方法异步化(参考SOFABoot的异步初始化方法实现)。对于日常/预发环境,提供命令行工具,实现一个命令完成热加载。
Spring在启动过程中对于Bean的加载是顺序进行的,如果存在部分Bean加载耗时比较严重时,应用的启动时长会被严重拉长。Bean的加载耗时主要在init-method
方法或@PostConstruct
标识的方法,容器中的Bean多数不存在依赖关系,如果可以将Bean的初始化方法异步化,可以大大降低启动耗时。
主要依赖Spring提供一个BeanPostProcessor
扩展点实现。BeanPostProcessor
允许我们自定义bean的实例化和初始化过程。它是一个接口,定义了两个方法:
postProcessBeforeInitialization(Object bean, String beanName):在bean初始化之前调用该方法,可以在初始化之前对bean对象进行任何自定义的修改或增强。 postProcessAfterInitialization(Object bean, String beanName):在bean初始化之后调用该方法。可以在bean初始化后对其进行任何自定义的修改或增强。 流程如下:
-
实现BeanPostProcessor扩展点
- 在postProcessBeforeInitialization中判断beanName是否是配置异步初始化Bean
- 如果需要异步化,查找init-method或者@PostConstruct修饰的方法
- 动态代理初始化方法,将初始化方法扔到线程池中执行,并返回Future
-
实现ApplicationListener
- 监听ContextRefreshedEvent事件,等待所有异步执行的init-method完成;
-
异步化的Bean可能在Spring Bean初始化顺序的末尾,导致异步优化效果不佳,支持优先加载配置异步化的Bean
- InstantiationAwareBeanPostProcessorAdapter可以做到在Bean实例化之前,预先回调。优先加载异步初始化的Bean。
热加载的思路来自一个issue,通过这个issue接触到了trava-jdk-8-dcevm,其基于 DCEVM 并集成了 HotswapAgent ,与标准 JDK 不同(只支持方法体内代码修改的热加载),其允许更高级的热部署,如方法、字段添加等等,如果在日常/预发环境使用trava-jdk的热加载能力,日常开发效率可以有很大的提升。
但是因为日常开发中部署分支和开发分支往往不是同一个分支,要想使用此能力,需要一些操作步骤有点繁琐,所以便实现了一个命令行工具,支持一个命令实现代码热加载。原理如下:
效果如下: