手底下有個專案 啟動需要140s,2分鐘以上了,需要最佳化
確定原因
使用 Spring Startup Analyzer
視覺化 啟動時間的分佈,發現 @Bean的 初始化佔用了 大部分時間
啟動耗時分佈
@Bean的 掃描放到 ioc中 ,平均MapperFactoryBean 經過 classLoader 一個bean 要200ms左右
@Bean的init方法(比如rpc呼叫其他專案介面,介面返回慢)
掃描 多餘jar
怎麼節省啟動時間
針對耗時,有2個辦法
減少@Bean 需要掃描的Class
減少@Bean 掃描放到ioc的耗時
@Bean 的init 非同步化
降低 rpc等自身呼叫耗時,最佳化程式碼和介面效能
去掉多餘的jar
springboot3 native化,省去了 JVM 載入和位元組碼執行期預熱的時間
針對上面提出的辦法 進行調研
減少@Bean 需要掃描的Class
平時寫元件的時候 要把需要掃描的bean 透過spring.factories 進行準確指定,現在的問題是透過@SpringBootApplication 的scanBasePackages 進行大範圍的掃描,導致掃描了無用的bean,同時要在寫業務專案的時候,要在公司 公共的包名後面 新增 業務專屬的標識,這樣能防止 掃描無用的bean
減少@Bean 掃描放到ioc的耗時
2 org.mybatis.spring.mapper.MapperFactoryBean 生成一個 mapper的代理需要200ms左右,首先需要確定這200ms 都花費在哪,我用的是 arthas
MapperFactoryBean主要分為
獲取 sqlSession
return mapperProxyFactory.newInstance(sqlSession); 生成mapper代理,放到 spring ioc中
但是這裏遇到一個問題,arthas 只能trace 一層,不能遞迴輸出下層的細節耗時
@Bean 的init 非同步化
這個能提升點效能,目前主要有2種
SOFABoot
spring6.2
SOFABoot 原理:
SOFABoot 缺點:
必須手動指定非同步化的Bean,其實手動指定,就已經輸了,畢竟難度和體驗感都差很多
最近從why哥 那看到spring6.2 已經開發了非同步bean,本來以為spring 官方應該就不用手動指定非同步化的Bean了,結果編譯spring6.2 然後測試了一下,還是需要指定非同步的bean
這個能提升啟動速度,但是不是重點,先放放
降低 rpc等自身呼叫耗時,最佳化程式碼和介面效能
這個就是根據耗時比較長的,看是哪部分的問題,然後最佳化效能,如果使用非同步,需要防止沒載入完成,就被呼叫的問題
去掉多餘的jar
有的jars 沒有被使用,而載入了,可能是後面開發的時候 引入的,然後對功能沒影響,就沒有刪除多餘的
可以從 Spring Startup Analyzer 中 Unused Jars After Startup 展示了,可以針對性刪除
springboot3 native化,省去了 JVM 載入和位元組碼執行期預熱的時間
它是省去了 JVM 載入和位元組碼執行期預熱的時間, 屬於把時間花費在 程式碼編譯階段,後面啟動 秒級
而且這是springboot 未來趨勢
需要寫一個springboot3 高效能基礎骨架
這裏先埋個坑,後面有時間了補上~