Spring Boot 性能優(yōu)化

Spring 框架給企業(yè)軟件開(kāi)發(fā)者提供了常見(jiàn)問(wèn)題的通用解決方案鹃栽,包括那些在未來(lái)開(kāi)發(fā)中沒(méi)有意識(shí)到的問(wèn)題箫踩。但是啤握,它構(gòu)建的 J2EE 項(xiàng)目變得越來(lái)越臃腫奴艾,逐漸被 Spring Boot 所替代。Spring Boot 讓我們創(chuàng)建和運(yùn)行項(xiàng)目變得更為迅速糯俗,現(xiàn)在已經(jīng)有越來(lái)越多的人使用它禁熏。我們已經(jīng)在幾個(gè)項(xiàng)目中使用了 Spring Boot 敏簿,今天我們就來(lái)一起討論一下如何改進(jìn) Spring Boot 應(yīng)用的性能涎跨。

首先洼冻,從之前我在開(kāi)發(fā)中遇到的一個(gè)問(wèn)題說(shuō)起。在一次查看項(xiàng)目運(yùn)行日志的時(shí)候隅很,我偶然發(fā)現(xiàn)了一個(gè)問(wèn)題撞牢,日志里顯示這個(gè)項(xiàng)目總是加載 Velocity 模板引擎,但實(shí)際上這個(gè)項(xiàng)目是一個(gè)沒(méi)有 web 頁(yè)面的 REST Service 項(xiàng)目叔营。于是我花了一點(diǎn)時(shí)間去尋找產(chǎn)生這個(gè)問(wèn)題的原因普泡,以及如何改進(jìn) Spring Boot 應(yīng)用的性能。在查找了相關(guān)的資料后审编,我得出的結(jié)論如下:

組件自動(dòng)掃描帶來(lái)的問(wèn)題

默認(rèn)情況下,我們會(huì)使用 @SpringBootApplication 注解來(lái)自動(dòng)獲取的應(yīng)用的配置信息歧匈,但這樣也會(huì)給應(yīng)用帶來(lái)一些副作用垒酬。使用這個(gè)注解后,會(huì)觸發(fā)自動(dòng)配置( auto-configuration )和 組件掃描 ( component scanning )件炉,這跟使用 @Configuration勘究、@EnableAutoConfiguration 和 @ComponentScan 三個(gè)注解的作用是一樣的。這樣做給開(kāi)發(fā)帶來(lái)方便的同時(shí)斟冕,也會(huì)有兩方面的影響:

1口糕、會(huì)導(dǎo)致項(xiàng)目啟動(dòng)時(shí)間變長(zhǎng)。當(dāng)啟動(dòng)一個(gè)大的應(yīng)用程序,或?qū)⒆龃罅康募蓽y(cè)試啟動(dòng)應(yīng)用程序時(shí)磕蛇,影響會(huì)特別明顯景描。

2、會(huì)加載一些不需要的多余的實(shí)例(beans)秀撇。

3超棺、會(huì)增加 CPU 消耗。

針對(duì)以上兩個(gè)情況呵燕,我們可以移除 @SpringBootApplication 和 @ComponentScan 兩個(gè)注解來(lái)禁用組件自動(dòng)掃描棠绘,然后在我們需要的 bean 上進(jìn)行顯式配置:

// 移除 @SpringBootApplication and @ComponentScan, 用 @EnableAutoConfiguration 來(lái)替代
@Configuration
@EnableAutoConfiguration
public class SampleWebUiApplication {

    // ...

    // 用 @Bean 注解明確顯式配置,以便被 Spring 掃描到
    @Bean
    public MessageController messageController(MessageRepository messageRepository) {
        return new MessageController(messageRepository);
    }

如何避免組件自動(dòng)掃描帶來(lái)的問(wèn)題

我們?cè)谏厦嫣岬剑珸SpringBootApplication 注解的作用跟 @EnableAutoConfiguration 注解的作用是相當(dāng)?shù)难醪裕蔷鸵馕吨材軒?lái)上述的三個(gè)問(wèn)題夜矗。要避免這些問(wèn)題,我們就要知道我們需要的組件列表是哪些让虐,可以用 -Ddebug 的方式來(lái)幫助我們明確地定位:

mvn spring-boot:run -Ddebug
…
=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:
-----------------

   DispatcherServletAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - found web application StandardServletEnvironment (OnWebApplicationCondition)

...

接著拷貝 Positive matches 中列出的信息:

DispatcherServletAutoConfiguration
EmbeddedServletContainerAutoConfiguration
ErrorMvcAutoConfiguration
HttpEncodingAutoConfiguration
HttpMessageConvertersAutoConfiguration
JacksonAutoConfiguration
JmxAutoConfiguration
MultipartAutoConfiguration
ServerPropertiesAutoConfiguration
PropertyPlaceholderAutoConfiguration
ThymeleafAutoConfiguration
WebMvcAutoConfiguration
WebSocketAutoConfiguration

然后來(lái)更新項(xiàng)目配置紊撕,顯式地引入這些組件,引入之后澄干,再運(yùn)行一下應(yīng)用確保沒(méi)有錯(cuò)誤發(fā)生:

@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        JmxAutoConfiguration.class,
        MultipartAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        ThymeleafAutoConfiguration.class,
        WebMvcAutoConfiguration.class,
        WebSocketAutoConfiguration.class,
})
public class SampleWebUiApplication {

在上面的代碼中逛揩,我們可以刪掉我們不需要的組件信息,來(lái)提高應(yīng)用的性能麸俘,比如在我的項(xiàng)目中辩稽,不需要 JMX 和 WebSocket 功能,我就刪掉了它們从媚。刪掉之后逞泄,再次運(yùn)行項(xiàng)目,確保一切正常拜效。

將Servlet容器變成Undertow

默認(rèn)情況下喷众,Spring Boot 使用 Tomcat 來(lái)作為內(nèi)嵌的 Servlet 容器。我們可以啟動(dòng)項(xiàng)目紧憾,然后用 VisualVM 或者 JConsole 來(lái)查看應(yīng)用所占的內(nèi)存情況:

Spring Boot 性能優(yōu)化

以上是我使用 Spring Boot 的默認(rèn)方式啟動(dòng)應(yīng)用后到千,用 VisualVM 監(jiān)控到的內(nèi)存的占用情況:堆內(nèi)存占用 110M,16 個(gè)線程被開(kāi)啟赴穗。

可以將 Web 服務(wù)器切換到 Undertow 來(lái)提高應(yīng)用性能憔四。Undertow 是一個(gè)采用 Java 開(kāi)發(fā)的靈活的高性能 Web 服務(wù)器,提供包括阻塞和基于 NIO 的非堵塞機(jī)制般眉。Undertow 是紅帽公司的開(kāi)源產(chǎn)品了赵,是 Wildfly 默認(rèn)的 Web 服務(wù)器。首先甸赃,從依賴信息里移除 Tomcat 配置:

<exclusions>
        <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
</exclusions>

然后添加 Undertow:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

啟動(dòng)項(xiàng)目后柿汛,用 VisualVM 監(jiān)控到的信息顯示:堆內(nèi)存占用 90M,13個(gè)線程被開(kāi)啟埠对。

Spring Boot 性能優(yōu)化

總結(jié)

這些都是我們?cè)陧?xiàng)目開(kāi)發(fā)中使用到的一些優(yōu)化 Spring
Boot 應(yīng)用的小技巧络断,對(duì)于大的應(yīng)用性能的提高還是很明顯的。大家可以嘗試一下项玛,然后告訴我們你的測(cè)試結(jié)果妓羊。

最后,附上代碼稍计,大家可以去這里下載:spring-boot-performance躁绸。

文中大部分內(nèi)容參考英國(guó)一個(gè)架構(gòu)師的博客DZone 近期發(fā)布的文章,在此感謝兩位大牛。參考文章及鏈接:

(1)Spring Boot 性能優(yōu)化:Spring Boot Performance净刮;

(2)Spring Boot 內(nèi)存優(yōu)化:Spring Boot Memory Performance剥哑。

(3)https://www.techempower.com/benchmarks/

(4)Spring 應(yīng)用程序優(yōu)化:Optimizing Spring Framework for App Engine Applications淹父。

OneAPM 為您提供端到端的 Java 應(yīng)用性能解決方案株婴,我們支持所有常見(jiàn)的 Java 框架及應(yīng)用服務(wù)器,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸暑认,定位異常根本原因困介。分鐘級(jí)部署,即刻體驗(yàn)蘸际,Java 監(jiān)控從來(lái)沒(méi)有如此簡(jiǎn)單座哩。想閱讀更多技術(shù)文章,請(qǐng)?jiān)L問(wèn) OneAPM 官方技術(shù)博客粮彤。

本文轉(zhuǎn)自 OneAPM 官方博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末根穷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子导坟,更是在濱河造成了極大的恐慌屿良,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惫周,死亡現(xiàn)場(chǎng)離奇詭異尘惧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)递递,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)喷橙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人漾狼,你說(shuō)我怎么就攤上這事〖⒈郏” “怎么了逊躁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)隅熙。 經(jīng)常有香客問(wèn)我稽煤,道長(zhǎng),這世上最難降的妖魔是什么囚戚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任酵熙,我火速辦了婚禮,結(jié)果婚禮上驰坊,老公的妹妹穿的比我還像新娘匾二。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布察藐。 她就那樣靜靜地躺著皮璧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪分飞。 梳的紋絲不亂的頭發(fā)上悴务,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音譬猫,去河邊找鬼讯檐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛染服,可吹牛的內(nèi)容都是我干的别洪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼肌索,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蕉拢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诚亚,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晕换,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后站宗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體闸准,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年梢灭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夷家。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敏释,死狀恐怖库快,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钥顽,我是刑警寧澤义屏,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站蜂大,受9級(jí)特大地震影響闽铐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奶浦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一兄墅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澳叉,春花似錦隙咸、人聲如沸沐悦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)所踊。三九已至,卻和暖如春概荷,著一層夾襖步出監(jiān)牢的瞬間秕岛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工误证, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留继薛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓愈捅,卻偏偏與公主長(zhǎng)得像遏考,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蓝谨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容