優化spring boot應用後6s內啟動內存減半
前言
taptap-developer是一個spring boot框架驅動的純Grpc服務,所以,隻用瞭四步,移除瞭web和spring cloud相關的模塊後,啟動速度就穩穩的保持在瞭6s內。除瞭啟動速度提升外,在服務待機狀態下,內存銳減瞭50%左右,從500M左右的內存占用,縮減到瞭250M不到。
分析日志
日志是一個應用的門面,在未深入瞭解一個應用的架構前,通過啟動的日志輸出基本可以分析出這個應用的大概的技術構成。在分析日志之前,在強調一點,這個應用是一個純Grpc的服務。如上圖貼出的日志,是未優化前的系統日志輸出,從上到下有四個紅色箭頭指向,是本次日志分析的關鍵信息,下面就這四個關鍵信息,分別分析下。然後總結出常見的優化方法
優化點一:關於SPRING DATA REPOSITORY SCANNING
Spring Data repository是一個高度抽象的數據訪問層接口,常見的實現有redis、jdbc、jpa、MongoDB、elasticsearch等等。實現一個Spring-data-xxx包,需要實現
org.springframework.data.repository.core.support.RepositoryFactorySupport抽象類
然後在!/META-INF/spring.factories文件中定義好實現類。spring容器啟動時,會掃描加載factories的信息。如果一個項目裡有被掃描到有多個spring-data-xxx的實現,啟動時日志就會打印
Multiple Spring Data modules found, entering strict repository configuration mode!
優化:看到這個日志,我們就需要檢查下項目中是否用到瞭這些功能,比如引入瞭spring-data-redis,其實隻用到瞭其攜帶的jedis,而且jedis實例可能還是自己實例化的,這個時候就可以禁用repository的功能。參考配置如下:
spring.data.redis.repositories.enabled=false
Spring Data repository有三種內置的初始化模式,分別對應如下:
DEFAULT
:和Spring其他Bean一樣,在容器上下文加載時就初始化DEFERRED
:惰性加載,容器上下文啟動完成後開始初始化LAZY
:惰性加載,並且延遲註入,容器上下文啟動完成接收第一個請求時開始初始化
如日志輸出:Bootstrapping Spring Data repositories in DEFAULT mode,默認是隨容器啟動就開始初始化的
優化:這裡可以根據業務特點,選擇延遲加載,
參考配置spring.data.jpa.repositories.bootstrap-mode=lazy
Spring Data repository會掃描項目中的實現瞭repository接口的類,默認情況下會盲掃所有的jar包,
日志輸出:Finished Spring Data repository scanning in 148ms. Found 0 repository interfaces.
打印出瞭掃描repository接口的耗時情況。
優化:
這裡可以通過@EnableRedisRepositories(basePackages = "com.taptap")指定掃描的路徑
可以顯著提升掃描加載的速度
優化點二:關於WEBAPPLICATIONCONTEXT
在spring中,WebApplicationContext是ApplicationContext的增強,由spring-web-mvc實現,增加瞭servlet、session等web相關的內容。
從日志Initializing Spring embedded WebApplicationContext可以看出,我們初始化瞭一個web容器,而純Grpc服務用不到Web的容器上下文,所以移除如下依賴即可
優化:
移除implementation('org.springframework.boot:spring-boot-starter-web')
優化點三:關於SERVLET容器
spring-web-mvc是基於java web標準servlet設計架構的。而servlet是由servlet容器來驅動的,常見的servlet有tocmat、jetty、undertow等。從日志中可看出,我們啟動瞭一個8081的servlet容器。這個不應該出現在純Grpc的服務中,所以,直接移除即可。
優化:
移除implementation 'org.springframework.boot:spring-boot-starter-undertow'
優化點四:關於ARCHAIUS配置組件
從最後一個箭頭指向的日志信息可以分析出,項目引入瞭archaius配置加載組件,所以項目在啟動時,archaius會嘗試去加載默認策略的配置源。而我們整體的技術棧,配置中心統一采用瞭apollo,所以可以直接移除,最後通過分析定位,archaius不是單獨引入的,是隨著spring-cloud-starter-netflix-hystrix一同引入,這個組件是spring-cloud-netflix微服務框架最常用的,但是在這邊,目前所有的微服務都是直接註冊到k8s容器的,所有服務的熔斷、限流、負載均衡都下沉到瞭容器基數設施平臺,所以應用層面雖然引入瞭這個包,其實沒有實際作用,所以最後移除spring cloud相關組件
優化:
移除implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'和
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'組件、
附優化後的日志輸出:
系統資源的變化
優化前的
優化後的
最後,基於資源監控圖,從三個維度總結下,優化後的資源占用情況:
資源名稱 | 優化前 | 優化後 |
---|---|---|
內存 | 500M左右 | 250M左右 |
總線程數 | 107 | 78 |
裝載類 | 12922 | 10041 |
以上就是優化spring boot應用後6s內啟動內存減半的詳細內容,更多關於spring boot應用優化的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 關於SpringCloud的微服務以及組件詳解
- Java Springboot之Spring傢族的技術體系
- spring boot教程之產生的背景及其優勢
- SpringCloud微服務基礎簡介
- 深入剖析網關gateway原理