吊打 Tomcat ,Undertow 性能很炸!!
在 Java Web 容器的世界里,Tomcat 和 Jetty 是大名鼎鼎的、用的最多的開源項(xiàng)目,也是大眾熟知的。
今天再介紹另外一款能和 Tomcat 媲美的神器:Undertow,據(jù)說(shuō)性能方面還要吊打 Tomcat,如果你還不知道它,那你就 OUT 了。
我們來(lái)看下 Spring Boot 默認(rèn)支持的三種 Servlet 容器:
| Tomcat 9.0 | 4.0 |
| Jetty 9.4 | 3.1 |
| Undertow 2.0 | 4.0 |
以上來(lái)源于 Spring Boot 2.3.2 官方文檔,更多信息請(qǐng)點(diǎn)擊這里參考這篇文章。
Undertow 它能成為 Spring Boot 默認(rèn)集成的三大容器之一,就憑這點(diǎn),我想就足以說(shuō)明它的地位。
Undertow 什么鬼?
Undertow 是 RedHat(紅帽公司)的開源產(chǎn)品,采用 Java 開發(fā),是一款靈活、高性能的 Web 服務(wù)器,提供了基于 NIO 的阻塞/非阻塞 APIs,也是 Wildfly 的默認(rèn) Web 容器。
搜索 Undertow:
頁(yè)面顯示的是 JBoss Community,因?yàn)?2006 年 RedHat 收購(gòu)了 JBoss,那也就不足為怪了。
Undertow 它是一個(gè)基于組合的體系結(jié)構(gòu),可以通過(guò)組合一系列小型處理器來(lái)構(gòu)建一個(gè) Web 服務(wù)器。這就讓我們可以靈活的在 Java EE servlet 4.0 容器和底層非阻塞處理器或者其他更多之間進(jìn)行選擇。
Undertow 被設(shè)計(jì)成完全可嵌入式的,所以也叫嵌入式容器,具有易于使用的流暢構(gòu)建 API,另外,Undertow 的生命周期也完全由所嵌入的應(yīng)用程序所控制。
這也是為什么 Spring Boot 可以直接嵌入 Undertow 的原因,Undertow 它就是為了嵌入而發(fā)燒的。Spring Boot 基礎(chǔ)知識(shí)就不介紹了,關(guān)注公眾號(hào)Java技術(shù)棧在后臺(tái)回復(fù)boot獲取我寫的系列教程。
官方網(wǎng)站:
https://undertow.io/
源碼托管在 Github:
https://github.com/undertow-io/undertow
Undertow 有啥特性?
1)HTTP/2 Support
Undertow 支持 HTTP/2 開箱即用,不需要重寫引導(dǎo)類路徑。
2)支持 HTTP 升級(jí)
支持 HTTP 升級(jí),允許多個(gè)協(xié)議通過(guò) HTTP 端口上進(jìn)行復(fù)用。
3)支持 Web Socket
Undertow 提供對(duì) Web 套接字的全面支持,包括對(duì) JSR-356 的支持。
4)支持 Servlet 4.0
Undertow 提供了對(duì) Servlet 4.0 的支持,包括對(duì)嵌入式 Servlet 的支持,還可以混合部署 Servlet 和原生 Undertow 非阻塞處理程序。
5)可嵌入式
Undertow 可以嵌入到應(yīng)用程序中,也可以通過(guò)幾行代碼獨(dú)立運(yùn)行。
6)高靈活性
一個(gè) Undertow 服務(wù)器是通過(guò)鏈?zhǔn)教幚砥鱽?lái)配置的,可以根據(jù)需要添加功能,因此可以避免添加沒(méi)有必要的功能。
Undertow 性能如何?
國(guó)外有篇帖子做了 Tomcat vs. Jetty vs. Undertow 三者的性能比較:
https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-of-spring-boot-embedded-servlet-containers/
?
從測(cè)試結(jié)果看,這三個(gè) Servlet 容器都具有不錯(cuò)的性能,但 Undertow 性能更好,Tomcat 和 Jetty 緊隨其后。
Jetty 在啟動(dòng)時(shí)的內(nèi)存占用最大,為:311 MB, Tomcat 和 Undertow 的初始內(nèi)存占用都很低,大約為:120 MB,而 Undertow 的初始內(nèi)存占用最低,為:114 MB。
最后,關(guān)鍵的區(qū)別在于,Undertow 響應(yīng)頭參數(shù)默認(rèn)包含 HTTP 持久連接信息,這個(gè)頭參數(shù)在支持持久連接的客戶端時(shí),可以通過(guò)重用連接來(lái)優(yōu)化性能。
Show me the code
Undertow 目前有兩個(gè)主要版本:
-
2.1:當(dāng)前支持 Servlet 4.0, JDK8+ 的穩(wěn)定版本;
-
1.4:當(dāng)前支持 Servlet 3.1, JDK7 的穩(wěn)定版本;
獨(dú)立使用 Undertow 需要添加以下依賴:
<dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>2.1.0.Final</version> </dependency><dependency><groupId>io.undertow</groupId><artifactId>undertow-servlet</artifactId><version>2.1.0.Final</version> </dependency><dependency><groupId>io.undertow</groupId><artifactId>undertow-websockets-jsr</artifactId><version>2.1.0.Final</version> </dependency>以下示例來(lái)源官網(wǎng):
public?class?HelloWorldServer?{public?static?void?main(final?String[]?args)?{Undertow?server?=?Undertow.builder().addHttpListener(8080,?"localhost").setHandler(new?HttpHandler()?{@Overridepublic?void?handleRequest(final?HttpServerExchange?exchange)?throws?Exception?{exchange.getResponseHeaders().put(Headers.CONTENT_TYPE,?"text/plain");exchange.getResponseSender().send("Hello?World");}}).build();server.start();} }這是一個(gè)使用了異常 IO 的簡(jiǎn)單 Hello World 示例。
Spring Boot & Undertow
上面講到,Undertow 是為嵌入式而生的 Web 容器,又是 Spring Boot 默認(rèn)集成的容器之一,下面棧長(zhǎng)帶大家來(lái)看下如何在 Spring Boot 中使用 ?Undertow。
因?yàn)樵?spring-boot-starter-web?啟動(dòng)器中,Tomcat 是 Spring Boot 默認(rèn)的嵌入式容器,即:spring-boot-starter-tomcat。
Spring Boot 還提供了其他兩個(gè)啟動(dòng)器以方便進(jìn)行代替:
-
spring-boot-starter-jetty
-
spring-boot-starter-undertow
下面來(lái)簡(jiǎn)單實(shí)戰(zhàn)下,如何在 Spring Boot 中使用 Undertow。Spring Boot 基礎(chǔ)知識(shí)就不介紹了,不熟悉的可以關(guān)注公眾號(hào)Java技術(shù)棧在后臺(tái)回復(fù)boot獲取我寫的系列教程。
排除 Tomcat 依賴,然后加入 Undertow 依賴:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><!--?Exclude?the?Tomcat?dependency?--><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!--?Use?Undertow?instead?--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency></dependencies>一步就完成集成了,當(dāng)然實(shí)際情況還需要在 application 配置文件中加入 Undertow 的更多自定義或者優(yōu)化配置參數(shù)。
Undertow容器的具體配置可以看這兩個(gè)類:
-
org.springframework.boot.autoconfigure.web.ServerProperties
-
org.springframework.boot.autoconfigure.web.ServerProperties.Undertow
也可以看 Spring Boot 官方文檔:
https://docs.spring.io/spring-boot/docs/2.3.2.RELEASE/reference/htmlsingle/#server-properties
上面有所有 Server 配置參數(shù)和說(shuō)明。
再寫一個(gè)測(cè)試方法測(cè)試下:
import?org.springframework.boot.SpringApplication; import?org.springframework.boot.autoconfigure.SpringBootApplication; import?org.springframework.web.bind.annotation.GetMapping; import?org.springframework.web.bind.annotation.RestController;/***?微信公眾號(hào):Java技術(shù)棧*/ @RestController @SpringBootApplication public?class?Application?{public?static?void?main(String[]?args)?{SpringApplication.run(Application.class);}@GetMapping(value?=?"/undertow/test")public?String?undertow()?{return?"hello?undertow";}}啟動(dòng) Application:
如上所示,可以看到 Undertow 的啟動(dòng)日志。
訪問(wèn)測(cè)試方法:
http://localhost:8080/undertow/test
輸出成功,測(cè)試完成。
總結(jié)
本文對(duì) Undertow 作了一個(gè)介紹和集成實(shí)戰(zhàn),雖然 Undertow 性能很炸,但你可以去網(wǎng)上找一圈,根本沒(méi)啥學(xué)習(xí)資料。
所以,對(duì)于學(xué)習(xí)和一般應(yīng)用來(lái)說(shuō),Tomcat 足矣,一方面 Tomcat 學(xué)習(xí)資料多,另一方面 Tomcat 用的更廣泛,很多坑別人幫你踩了,很多漏洞也已經(jīng)暴露出來(lái)了。
那于那些一定要追求極致性能的又不想優(yōu)化 Tomcat 的,可以考慮使用 Undertow,但同時(shí)你要有能力 Hold 住它,需要一定的積累經(jīng)驗(yàn),不然出一個(gè)問(wèn)題你線上卡半天顯然是不愿意看到的。
最后,網(wǎng)上很多文章說(shuō)干掉 Tomcat 而要使用 Undertow 的,這就有點(diǎn)夸張,我只能呵呵了,持有保留意見(jiàn),用啥都行,關(guān)鍵能不能用好。
總結(jié)
以上是生活随笔為你收集整理的吊打 Tomcat ,Undertow 性能很炸!!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大环境下瑟瑟发抖辞职的第二天,拿了两个
- 下一篇: Serverless的4种错误打开方式