「SpringBoot 新特性」啟動耗時詳細監(jiān)控
背景
Spring Boot 項目隨著項目開發(fā)過程中引入中間件數(shù)量的增加,啟動耗時 逐漸增加。
筆者在 《Spring Boot 2.4.0 正式 GA,全面擁抱云原生》[1]文章發(fā)現(xiàn)如下評論

Spring 生態(tài)復雜,非官方插件并未嚴格按官方標準實現(xiàn)。例如 @Configuration 注解提供了 proxyBeanMethods 屬性默認開啟,建議常見情況手動關(guān)閉提高性能。筆者在觀察大部分非官方插件 stater 并未引入此屬性。諸如此類的優(yōu)化策略很多(建議翻一下筆者歷史博客),但往往被開發(fā)者忽略,導致使用該插件會影響應用啟動效率。

啟動過程中串行初始化邏輯較多,嚴重影響啟動效率。例如 Druid 數(shù)據(jù)庫連接池初始化設(shè)置不合理導致創(chuàng)建物理鏈接緩慢影響啟動效率[2]。
如上兩點,我認為 SpringBoot 啟動緩慢和框架本身沒有太大關(guān)系,取決于開發(fā)者的能力。如何能夠在開發(fā)中準確的分析啟動過程,定位到每個耗時操作?單純從啟動日志的維度是無法實現(xiàn),Spring Boot 2.4.0 提供了啟動過程監(jiān)控的端點,非常方便的讓開發(fā)者在開發(fā)過程中觀察每個組件的初始化過程、消耗時間等。
上手體驗
引入 actuator依賴
<dependency>
??<groupId>org.springframework.bootgroupId>
??<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
配置暴露 startup端點
management:
??endpoints:
????web:
??????exposure:
????????include:?startup
Main 啟動類聲明緩沖池,這里注意若應用依賴較多,建議把 capacity 容量參數(shù)設(shè)置大些,盡可能的保留全部監(jiān)控日志。
@SpringBootApplication
public?class?DemoApplication?{
????public?static?void?main(String[]?args)?{
????????//?建議僅在開發(fā)或者排除時開啟此配置
????????new?SpringApplicationBuilder(DemoApplication.class)
????????????????.applicationStartup(new?BufferingApplicationStartup(20480))
????????????????.run(args);
????}
}
獲取啟動數(shù)據(jù) ,POST 請求 /actuator/startup端點返回監(jiān)控數(shù)據(jù)
?>?~?curl?-XPOST?http://localhost:8080/actuator/startup?????????????????11:49:51
{"springBootVersion":"2.4.0","timeline":{"startTime":"2020-12-04T01:38:15.028114Z","events":[{"startupStep":{"name":"spring.event.invoke-listener","id":296,"parentId":0,"tags":[{"key":"event","value":"ServletRequestHandledEvent:?url=[/actuator/startup];?client=[0:0:0:0:0:0:0:1];?method=[POST];?servlet=[dispatcherServlet];?session=[null];?user=[null];?time=[83ms];?status=[OK]"},{"key":"listener","value":"org.springframework.boot.context.config.DelegatingApplicationListener@2053d869"}]},"startTime":"2020-12-04T01:38:28.402870279Z","endTime":"2020-12-04T01:38:28.402929390Z","duration":"PT0.000059111S"}]}}
測試案例
新增 RestTemplate Bean,并模擬初始化耗時
@Configuration(proxyBeanMethods?=?false)
public?class?DemoConfiguration?{
????@Bean
????public?RestTemplate?restTemplate()?throws?InterruptedException?{
????????//?模擬初始化過程中的耗時操作
????????Thread.sleep(5000);
????????return?new?RestTemplate();
????}
}
獲取端點日志, 準確輸出在啟動過程中初始化 RestTemplate 耗時情況

根據(jù)耗時排序
端點接口并未提供相關(guān)的接口,而是按照啟動加載順序展示。沒有必要手動處理獲取這些數(shù)據(jù)排序,可以通過 https://www.bejson.com/json/jsonsort/ 在線格式化排序

選擇按照耗時排序即可

參考資料
Spring Boot 2.4: https://www.oschina.net/news/120443/spring-boot-2-4-0-released
[2]Druid : https://github.com/alibaba/druid/issues/1368
往期推薦
評論
圖片
表情
