背景
随着业务的复杂程度越来越大,所启动的实例或函数越来越多,Spring cloud 应用的启动越来越慢,那么如何发现 Spring 容器启动慢的原因或位置,有没有一款工具,帮助我们用户发现 Spring 应用启动慢的位置呢?同时,还可以提供 Spring Bean 异步初始化的工具。那么答案是有的。
下面,我们可以通过下面的方法尝试分析一下自己的应用吧,Let us go~
第一步:在 gitlab 网站下面其最新 tag:https://github.com/linyimin0812/spring-startup-analyzer/releases/tag/v2.0.5,下载tar.gz包。
第二步:解压下载的安装包,记住解压后的路径,下面一步要用:
第一步:编辑 Spring Boot 的启动参数,包括:
HOME 代表以前的解压路径,记得根据上面解压后的路径编辑这个参数,我的是:-javaagent:G:/Downloads/spring-startup-analyzer/lib/spring-profiler-agent.jar
英文版:
中文版:
spring-startup-analyzer:
admin:
http:
server:
port: 8065
app:
health:
check:
endpoints: "http://127.0.0.1:7002/actuator/health"
timeout: 10
async:
profiler:
interval:
millis: 5
sample:
thread:
names: main
最后一步:查看该工具的日志,可以通过
HOME 代表以前的解压路径,日志文件的类别为:
应用启动完成后会在 console 和 startup.log 文件中输出======= spring-startup-analyzer finished, click http://localhost:8065 to visit details. ======,可以通过此输出来判断采集是否完成。
当然,该组件还支持自定义扩展,更多详情请看:https://github.com/linyimin0812/spring-startup-analyzer/tree/v2.0.5#configuration。
这里提到了一个启动加速的优化思路,就是把一些耗时的 Bean 初始化改成异步就能实现。该项目提供了 Bean 的异步初始化工具,也非常好用,只需要下面几步就能完成。提供一个 Spring Bean 异步初始化 jar 包,针对初始化耗时比较长的 bean,异步执行 init 和@PostConstruct 方法提高应用启动速度。
第一步:引入依赖
<dependency>
<groupId>io.github.linyimin0812</groupId>
<artifactId>spring-async-bean-starter</artifactId>
<version>2.0.5</version>
</dependency>
第二步:配置参数
spring-startup-analyzer:
boost:
spring:
async:
## 指定异步的Bean名称
bean-names: restTemplate,testBean,testComponent
#异步化的Bean可能在Spring Bean初始化顺序的末尾,导致异步优化效果不佳,打开配置优先加载异步化的Bean
bean-priority-load-enable: true
# 执行异步化Bean初始化方法线程池的核心线程数
init-bean-thread-pool-core-size: 8
# 执行异步化Bean初始化方法线程池的最大线程数
init-bean-thread-pool-max-size: 8
第三步:检查 Bean 是否异步初始化。查看日志$HOME/spring-startup-analyzer/logs/startup.log 文件,对于异步执行初始化的方法,会按照以下格式写一条日志:
async-init-bean, beanName: ${beanName}, async init method: ${initMethodName}
但是,异步并不是万能的,你还需要注意以下这几点:
支持@Bean, @PostConstruct 及@ImportResource 方式初始化 bean
@Bean(initMethod = "init")标识的 Bean
@Bean(initMethod = "init")
public TestBean testBean() {
return new TestBean();
}
@Bean(initMethod = "init")
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(env.getProperty("client.http.request.readTimeout", Integer.class, 15000));
requestFactory.setConnectTimeout(env.getProperty("client.http.request.connectTimeout", Integer.class, 3000));
RestTemplate rt = new RestTemplate(requestFactory);
return rt;
}
@PostConstruct 标识的 Bean
@Component
public class TestComponent {
@PostConstruct
public void init() throws InterruptedException {
Thread.sleep(20 * 1000);
}
}
更多详情请看:https://github.com/linyimin0812/spring-startup-analyzer/blob/v2.0.5/README_ZH.md。