<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          這樣優(yōu)化后的 Spring Boot 項目,速度快的飛起來了。

          共 22853字,需瀏覽 46分鐘

           ·

          2021-11-15 12:06

          來源:http://rrd.me/ekc64

          “Spring有多快?”

          這是 2018 Spring One Platform 中的一場會議。看完會議視頻,我自己動手試了一下。下面是我做出的測試結(jié)果。

          還沒有觀看視頻的朋友推薦看一下,非常有意思。

          https://springoneplatform.io/2018/sessions/how-fast-is-spring-

          本文使用的代碼

          https://github.com/bufferings/spring-boot-startup-mybench

          我使用的是 OpenJDK 11。

          java --version
          openjdk 11.0.1 2018-10-16
          OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
          OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

          可以按照下面這樣運(yùn)行基準(zhǔn)測試。運(yùn)行起來可能需要一些時間,下面會執(zhí)行所有的測試。

          ./mvnw clean package
          (cd benchmarks/; java -jar target/benchmarks.jar)

          1. FluxBaseline

          我使用 SpringInitializr 創(chuàng)建項目,僅包含 Reactive Web。接下來,我會寫一個 WebMVC 風(fēng)格的極簡controller。

          @SpringBootApplication
          @RestController
          public class DemoApplication {

            @GetMapping("/")
            public String home() {
              return "Hello";
            }

            public static void main(String[] args) {
              SpringApplication.run(DemoApplication.class, args);
            }
          }

          Spring Boot 版本是 2.1.0.RELEASE。

          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.1.0.RELEASE</version>
              <relativePath/> <!-- lookup parent from repository -->
          </parent>

          啟動結(jié)果 2.938 ± 0.287 s/op。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op

          現(xiàn)在,以這個結(jié)果作為基線。讓我們從這里開始。

          2. WebMVC

          我很好奇為什么要用 WebMVC 而不是 WebFlux?我嘗試了一下。也許僅僅是為了比較 Tomcat 和 Netty?

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op

          WebFlux 快了一點(diǎn),難道不是嗎?

          3. spring-context-indexer

          接下來,我試了 spring-context-indexer,似乎創(chuàng)建了 component index。

          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context-indexer</artifactId>
              <optional>true</optional>
          </dependency>

          嗯…慢了一點(diǎn)點(diǎn)?

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op

          我檢查了 spring.components,發(fā)現(xiàn)只包含了一個組件。了解…我應(yīng)該嘗試更大一點(diǎn)的項目,這樣才能看到效果。

          #
          #Sun Nov 04 18:42:59 JST 2018
          com.example.DemoApplication=org.springframework.stereotype.Component

          4. 惰性初始化

          嘗試了惰性初始化。

          @Configuration
          public class LazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
            @Override
            public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              for (String beanName : beanFactory.getBeanDefinitionNames()) {
                beanFactory.getBeanDefinition(beanName).setLazyInit(true);
              }
            }
          }

          查看結(jié)果,啟動變快了一點(diǎn)。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op

          5. NoVerify

          運(yùn)行加 -noverify 選項:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op

          啟動變得快了一點(diǎn)。不知道為什么有這個結(jié)果,稍后需要仔細(xì)了解一下。

          6. TieredStopAtLevel

          運(yùn)行加 -XX:TieredStopAtLevel=1 選項:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op

          嗯,快多了!減少了幾乎2秒。還是不知道這個參數(shù)有什么含義,稍后需要仔細(xì)了解一下。

          7. 指定 SpringConfigLocation 參數(shù)

          運(yùn)行加 -Dspring.config.location=classpath:/application.properties 選項:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op

          嗯,又變慢了。

          8. 關(guān)閉 JMX

          運(yùn)行加 -Dspring.jmx.enabled=false 選項:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op

          變得快了一點(diǎn)。

          9. 取消 Logback

          從這里開始,我開始減少函數(shù)庫。開始,取消 Logback:

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-webflux</artifactId>
              <exclusions>
                  <exclusion>
                      <artifactId>spring-boot-starter-logging</artifactId>
                      <groupId>org.springframework.boot</groupId>
                  </exclusion>
              </exclusions>
          </dependency>
          <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-jdk14</artifactId>
          </dependency>

          結(jié)果如下:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op

          嗯…似乎有一點(diǎn)點(diǎn)改進(jìn)?

          10. 取消 Jackson

          接下來是 Jackson

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-webflux</artifactId>
              <exclusions>
                  <exclusion>
                      <artifactId>spring-boot-starter-json</artifactId>
                      <groupId>org.springframework.boot</groupId>
                  </exclusion>
              </exclusions>
          </dependency>

          結(jié)果如下:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op

          結(jié)果變快了一點(diǎn)。

          11. 取消 HibernateValidator

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-webflux</artifactId>
              <exclusions>
                  <exclusion>
                      <artifactId>hibernate-validator</artifactId>
                      <groupId>org.hibernate.validator</groupId>
                  </exclusion>
              </exclusions>
          </dependency>

          結(jié)果如下:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op

          也有一點(diǎn)效果。

          到這里為止,不再取消函數(shù)庫了。

          12. AppCDS

          AppCDS (Application Class Data Sharing) 是 Oracle JDK 的一個企業(yè)版功能。OpenJDK 10 開始包含了這個功能。

          看起來 AppCDS 轉(zhuǎn)儲信息存到了一個共享壓縮文件,所以啟動時間變短了。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op

          嗯…并沒有變快…然后我閱讀了CDS的相關(guān)文章,找到原因了。

          SpringBoot FatJAR 不在 CDS 管理范圍內(nèi)。

          13. 使用 Thin Launcher 的 Flux

          嗯,對不起,“Exploded” 基準(zhǔn)測試錯了。我曾經(jīng)試著使用 FatJAR,但是 CDS 不能這么干。所以,我轉(zhuǎn)而使用 Thin Launcher,所以 “Exploded” 就變成了 “Thin Launche”。

          使用 CDS 以前,我會測試使用 Thin Launcher 打包 JAR 文件的啟動速度。

          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot.experimental</groupId>
                          <artifactId>spring-boot-thin-layout</artifactId>
                          <version>1.0.15.RELEASE</version>
                      </dependency>
                  </dependencies>
              </plugin>
          </plugins>

          盡管我使用 Thin Launcher 打包 app,但并沒有使用 Thin Launcher 啟動類,而是使用 Main class 讓啟動盡可能快一些。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op

          嗯,快了一點(diǎn),對嗎?

          14. Thin Launcher + CDS

          現(xiàn)在,我要使用 AppCDS 。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op

          喔!變得更快了!

          15. 所有操作都上

          最終,我把所有操作都用上。

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op

          小于1秒鐘!(∩′?`)∩耶

          更進(jìn)一步

          在 Dave 的視頻中,他提到了“函數(shù)式 Bean 定義”,嘗試僅使用 Spring 不用 SpringBoot,app變得更快了。其中的道理還需要進(jìn)一步了解。

          結(jié)果:

          Benchmark                                          Mode  Cnt  Score   Error  Units
          MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
          MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op
          MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op
          MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op
          MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op
          MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op
          MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op
          MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op
          MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op
          MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op
          MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op
          MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op
          MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op
          MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op
          MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op

          真的很有意思。感謝!

          往期推薦

          3 行代碼寫出 8 個接口,牛逼!!這也行??

          一個基于Spring Boot+Vue+Redis的物聯(lián)網(wǎng)智能家居系統(tǒng),可二次開發(fā)接私活!

          SpringCloud+Docker+Jenkins+GitLab+Maven實現(xiàn)自動化構(gòu)建與部署實戰(zhàn)

          Java 開發(fā)常用的 Linux 命令知識積累

          配置 Nginx 的神器


          瀏覽 53
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  殴美成人精品 | 伊人天堂视频 | 亚洲综合婷婷 | 精品久久做 | 77777精品成人免费A片 |