後續之《SpringBoot伺服器壓測對比jetty、tomcat、undertow》

2020-12-12 虎兄龍弟

一、前言

昨天發了一個《SpringBoot伺服器壓測對比(jetty、tomcat、undertow)》,本是工作的一個筆記,沒想到被紅薯翻牌了(榮幸之至)。看了OSCer的回覆,感覺需要重新梳理下,因為確實存在描述不清和不合理的配置。

這篇博客的目的,不是複述上一篇博客,而是儘量規範的去做一次壓測對比,並且能夠清晰的描述出過程和結果。

二、準備

1、伺服器

為了保證儘量少的幹擾,這裡不再在虛擬機上運行服務,而是直接在物理機上運行服務,並且在這臺物理機上安裝ab工具。

伺服器配置是2個CPU,單個CPU8核,總共內存40G,1T的RAID5機械硬碟。伺服器安裝的系統是Centos7.5,系統優化同《Centos7高並發優化》所述。但額外的,因工作需要,這臺物理機上有6個虛機,是不能關閉的。以下是簡單的top展示:

2、測試項目

感謝@TGVvbmFyZA 的建議,測試項目不再使用生產項目,而是從Springboot官網打包2.x版本的項目,這樣的目的是減少生產項目中不必要的依賴,從而避免不必要的開銷。以下是簡單的項目介紹:

我已將項目放到Gitee,地址:https://gitee.com/loveliyiyi/test4server

以下貼出關鍵代碼,以便更好理解。

package com.shy.test4server;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.context.request.async.WebAsyncTask;/** * @ClassName: TestController * @Description: TODO(這裡用一句話描述這個類的作用) * @author chengcai.shang@cmgplex.com * @date 2018年12月7日 上午9:36:25 * */@Controller@RequestMapping("/test")publicclassTestController{ /** * 未使用HTTP異步的接口 * * @Title: testCeilingNoAsync * @Description: TODO(這裡用一句話描述這個方法的作用) * @date 2018年12月7日 上午9:40:57 */@GetMapping("/testCeilingNoAsync") public String testCeilingNoAsync(){ return""; } /** * 使用HTTP異步的接口 * * @Title: testCeilingNoAsync * @Description: TODO(這裡用一句話描述這個方法的作用) * @date 2018年12月7日 上午9:40:57 */@GetMapping("/testCeilingWithAsync") public WebAsyncTasktestCeilingWithAsync(){ returnnew WebAsyncTask(() -> { return""; }); }}

3、項目優化

不同的伺服器容器優化參數均不一致,以下是本次測試主要優化的地方:

以下優化步驟:

針對tomcat,在application.properties中加入server.tomcat.max-threads=400即可。

針對jetty,在config目錄加入JettyConfig類

package com.shy.test4server.config;import org.apache.catalina.Server;import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @ClassName: JettyConfig * @Description: TODO(這裡用一句話描述這個類的作用) * @date 2018年12月7日 上午9:53:46 * */@ConfigurationpublicclassJettyConfig{ @Beanpublic JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory( JettyServerCustomizer jettyServerCustomizer){ JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(); factory.addServerCustomizers(jettyServerCustomizer); return factory; } @Beanpublic JettyServerCustomizer jettyServerCustomizer(){ return server -> { threadPool(server); }; } privatevoidthreadPool(Server server){ // Tweak the connection config used by Jetty to handle incoming HTTP// connectionsfinal QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); // 默認最大線程連接數200 threadPool.setMaxThreads(100); // 默認最小線程連接數8 threadPool.setMinThreads(20); // 默認線程最大空閒時間60000ms threadPool.setIdleTimeout(60000); }}

針對undertow,在application.properties中加入server.undertow.io-threads=16和server.undertow.worker-threads=400即可

針對http異步,優化代碼如下:

package com.shy.test4server.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;/** * @ClassName: SpringmvcConfig * @Description: TODO(這裡用一句話描述這個類的作用) * @date 2018年12月7日 上午9:59:06 * */@ConfigurationpublicclassSpringmvcConfig{ @BeanpublicvoidconfigThreadPoll(AsyncSupportConfigurer asyncSupportConfigurer){ ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); threadPool.setCorePoolSize(10); threadPool.setMaxPoolSize(400); threadPool.setQueueCapacity(200); threadPool.initialize(); asyncSupportConfigurer.setTaskExecutor(threadPool); }}

另,所有測試中,日誌均關閉。

三、壓測方案

由於三個伺服器的優化參數不一致,沒法做統一配置,然後觀察結果。故只能不斷調整參數獲取最大的結果,然後比對最終結果,雖然這樣得出結果有點片面,但目前也只能這麼幹。另外,不再輔以Jprofiler監控,因為Jprofiler會影響一定得性能。以下是壓測步驟:

1、使用tomcat,壓測兩個接口,按不同並發訪問10000次,然後不斷調整參數,獲取最大結果。由此可得出純tomcat和tomcat+http異步的結果。

2、使用jetty,壓測兩個接口,按不同並發訪問10000次,然後不斷調整參數,獲取最大結果。由此可得出純jetty和jetty+http異步的結果。

3、使用udertow,壓測兩個接口,按不同並發訪問10000次,然後不斷調整參數,獲取最大結果。由此可得出純udertow和udertow+http異步的結果。

四、壓測過程

1、tomcat

啟動命令

java -server -Dserver.tomcat.max-threads=400 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

壓測命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

壓測結果:

2、jetty

啟動命令

java -server -Djetty.thread.max=400 -Djetty.thread.min=10 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

壓測命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

壓測結果:

3、undertow

啟動命令

java -server -Dserver.undertow.io-threads=16 -Dserver.undertow.worker-threads=400 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

壓測命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsyncab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsyncab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

壓測結果:

五、壓測結果

1、關於HTTP異步

HTTP異步的目的在幫助dispatcherservlet分擔壓力,提升吞吐量。但如果運行在NIO模式的服務容器上,就會產生負面影響,因為NIO本身就做了類似的事情,此時再加HTTP異步,則相當於又加了N多不必要的線程,導致性能主要消耗在線程的開銷上,所以建議使用tomcat作為內嵌容器並且沒有開啟tomcat的NIO模式時,可以配合HTTP異步來提升程序性能。尤其是當業務繁重時,提升效果尤其明顯。

2、關於服務容器

在基於天花板接口的測試中,綜合對比tomcat、jetty、undertow,可以發現undertow相對性能更高點。但此結果並不一定準確,因為測試方案裡只進行了很簡單的參數調整,以及並沒有針對實際業務代碼進行測試。不過源碼我已提供,有興趣的可以實際測試下。

著作權歸作者所有

相關焦點

  • Spring Boot中Tomcat、Jetty、Undertow的使用
    : 最大線程數server.jetty.threads.min: 最小線程數server.jetty.threads.max-queue-capacity: 最大隊列容量server.jetty.threads.idle-timeout: 線程最大空閒時間
  • 吊打Tomcat,Undertow 性能很炸!
    Undertow 是 RedHat(紅帽公司)的開源產品,採用 Java 開發,是一款靈活、高性能的 Web 伺服器,提供了基於 NIO 的阻塞/非阻塞 APIs,也是 Wildfly 的默認 Web 容器。
  • Spring Boot 集成undertow作為web容器
    版本:springboot:2.3.0tomcat:9undertow:2Spring Boot內嵌容器支持Tomcat、Jetty、Undertow。tomcat作為默認的容器。tomcat是apache基金會下一個開源項目。Undertow 是紅帽公司開發的一款基於 NIO 的高性能 Web 嵌入式伺服器。JBoss就是使用的undertow。
  • JFinal Undertow 1.4 發布,小版本迭代
    undertow 1.3 版本,這個版本已經十分完善好用    jfinal underow 1.4 針對自 1.3 發布以來的一些重要反饋進行了升級,具體升級內容如下:1、改進 session 熱加載    jfinal 俱樂部有位同學在使用過程中發現存放在 session 中的 model 對象在讀取時會碰到類型轉換異常,jfinal undertow
  • smart-servlet v0.1.0 首發,籌備了 3 年的開源 Servlet 伺服器
    儘管開源時長僅 1 個月,還有著諸多不成熟,但希望未來能成為如同 Tomcat、Undertow 般優秀的項目。為了這個目標,smart-servlet 準備了三年: 3年前,開源 AIO 通信框架 smart-socket。
  • Undertow 2.0.10 發布,高性能的嵌入式 Web 伺服器
    此外,Undertow 2.0 保持向後兼容 Undertow 1.4,但不再支持 JDK7。Maven<dependency>    <groupId>io.undertow</groupId>    <artifactId>undertow-core</artifactId>    <version>2.0.10.Final</version></dependency
  • java開發之Tomcat線程池優化
    前言:上期我們說到了jvm的內存優化,這期我們來說說tomcat的線程池優化,此思路同樣可用於c3p0等連接池tomcat線程池優化我們tomcat線程池的優化,其實就是最大限度的發揮tomcat的性能。即讓伺服器在保障性能的情況下並發最大並發:所有線程,在同一秒一起訪問同一個資源。
  • JFinal Undertow 2.0 發布,開發、打包、部署一體化
    jfinal-undertow 用於開發、部署由 jfinal 開發的 web 項目。
  • JFinal Undertow 1.5 發布,穩定、可靠服役於生產環境
    jfinal-undertow 用於開發、部署由 jfinal 開發的 web 項目。
  • 黑馬程式設計師:SpringBoot教程,SpringBoot高級之原理分析
    1.2、SpringBoot切換內置伺服器1.2.1、啟用內置web伺服器引入starter-web坐標之後,伺服器內置tomcat啟動了<dependencyartifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat
  • 初學者需要知道的springboot核心概念-java程式設計師漲工資技能
    一:Spring Boot 、 Spring MVC 、Spring對比首先你需要明白一件事情:Spring Boot項目目的並不是替換Spring、SpringMVC,而是使他們用起來更加簡單。springboot思考的方式:是不是可以更加智能一點,當Spring中加入一些新的jar包,可以自動的配置一些bean。 比如:Spring MVC JAR位於類路徑中時,自動配置Dispatcher Servlet。三、什麼是Spring Boot Starter?
  • Tomcat伺服器安裝、配置及驗證
    Tomcat伺服器安裝前,需要本地電腦上安裝有Java JDK,關於JDK的安裝請參考:Java JDK下載、安裝和驗證下面詳細介紹Tomcat 7.0的安裝配置及驗證步驟:1、到tomcat.apache.org官網上,下載Tomcat對應的版本,這裡選擇
  • SpringBoot開發常用的註解及作用
    隨著網際網路的快速發展,不斷的湧出新的技術,springboot是什麼呢?springboot它是spring開源組織下的子項目,主要是用來簡化spring的難度以及不足,節省程式設計師的繁重的配置,為程式設計師開發過程中各種啟動器。
  • 「Tomcat」Tomcat伺服器核心配置說明及標籤
    --定義伺服器的全局JNDI資源 --> <GlobalNamingResources/> <!-- port:關閉伺服器的監聽端 shutdown:關閉伺服器的指令字符串--><Server port="8005" shutdown="SHUTDOWN"> <!
  • 如何安裝並配置Tomcat10
    安裝Tomcat10首先打開tomcat的官網,找到左邊的Download,選擇你需要的版本,這裡攸攸選擇的是Tomcat10,點一下右邊往下拖在Core處選擇你需要的包點擊下載,我下載的是win64位。
  • 記一次jmeter壓測實戰總結
    三.測試結果分析1、有錯誤率同開發確認,確定是否允許錯誤的發生或者錯誤率允許在多大的範圍內;2、Throughput吞吐量每秒請求的數大於並發數,則可以慢慢的往上面增加;若在壓測的機器性能很好的情況下,出現吞吐量小於並發數,說明並發數不能再增加了,可以慢慢的往下減,找到最佳的並發數;3、壓測結束,登陸相應的web伺服器查看CPU等性能指標,進行數據的分析;4、最大的
  • SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合來實現Dubbo分布式事務
    3.1 github地址springboot-dubbo-seata:https://github.com/lidong1665/springboot-dubbo-seata-- lookup parent from repository -->    </parent>    <artifactId>springboot-dubbo-seata</artifactId>    <packaging>pom</packaging>    <name>springboot-dubbo-seata
  • springboot如何做到接口返回JSP頁面
    環境:IDEA、java、springboot、tomcat等相關開發工具. 解決訪問hello接口返回如下錯誤頁面還得回頭看看第9步中的註解,war包的不能用內嵌的容器啟動,於是又配置的外部tomcat啟動,如下圖配置tomcat server:可參考:https://blog.csdn.net/hadues/article/details/79334355