首頁 > 軟體

SpringBoot如何使用Undertow做伺服器

2022-07-07 14:04:53

使用Undertow做伺服器

說明

undertow,jetty和tomcat可以說是javaweb專案當下最火的三款伺服器,tomcat是apache下的一款重量級的伺服器,不用多說歷史悠久,經得起實踐的考驗。

然而:當下微服務興起,spring boot ,spring cloud 越來越熱的情況下,選擇一款輕量級而效能優越的伺服器是必要的選擇。

spring boot 完美整合了tomcat,jetty和undertow,本文將通過對jetty和undertow伺服器的分析以及測試,來比較兩款伺服器的效能如何。

值得一提的是jetty和undertow都是基於NIO實現的高並行輕量級的伺服器,支援servlet3.1和websocket。所以,有必要先了解下什麼是NIO。

NIO(非阻塞式輸入輸出)

  • Channel
  • Selector
  • Buffer
  • Acceptor

Client和Server只向Buffer讀寫資料不關注資料的流向,資料通過Channel通道進行流轉。而Selector是存在與伺服器端的,用於Channel的註冊以此實現資料I/O操作。Acceptor負責接受所以的連線通道並且註冊到Channel中。而整個過程使用者端與伺服器端是非阻塞的也就是非同步操作。

下面是壓力測試對比:

伺服器命中成功率吞吐量平均耗時
Jetty11488100%96.25 trans/sec0.00sec
18393100%153.92 trans/sec0.01sec
2148499.99%179.51 trans/sec0.01sec
Undertow11280100%94.02 trans/sec0.00sec
19442100%163.35 trans/sec0.01sec
23277100%195.54 tran/sec0.01sec
Tomcat10845100%90.95 trans/sec0.02sec
2167399.98%181 trans/sec0.01sec
2508499.98%209.10 trans/sec0.01sec

從中可以看出在高負載下Undertow的吞吐量高於Jetty而且隨著壓力增大Jetty和Undertow成功率差距會拉大。而在負載不是太大情況下伺服器處理能力差不多,jetty還略微高於Undertow。而tomcat的負載能力似乎和Undertow很接近。

對比三個伺服器發現在Undertow在負載過重情況下比Jetty和Tocmat更加頑強,實踐證明在負載繼續加大情況下Undertow的成功率高於其它兩者,但是在並行不是太大情況下三款伺服器整體來看差別不大。

快速開始

更新pom.xml檔案:

        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-web</artifactId>-->
        <!--</dependency>-->
 
        <!-- 下面的設定將使用undertow來做伺服器而不是tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

application.yml設定:

server:
  port: 8081
  # 下面是設定undertow作為伺服器的引數
  undertow:
    # 設定IO執行緒數, 它主要執行非阻塞的任務,它們會負責多個連線, 預設設定每個CPU核心一個執行緒
    io-threads: 4
    # 阻塞任務執行緒池, 當執行類似servlet請求阻塞操作, undertow會從這個執行緒池中取得執行緒,它的值設定取決於系統的負載
    worker-threads: 20
    # 以下的設定會影響buffer,這些buffer會用於伺服器連線的IO操作,有點類似netty的池化記憶體管理
    # 每塊buffer的空間大小,越小的空間被利用越充分
    buffer-size: 1024
    # 是否分配的直接記憶體
    direct-buffers: true

設定比較簡單,和tomcat使用基本一樣,然後就可以快樂的使用undertow啦~

undertow警告Buffer pool was not set on WebSocketDeploymentInfo

看提示讓你設定一下buffer pool,不然他就使用預設的

這個警告不影響使用,但是看著彆扭,於是

根據官方檔案,和原始碼,自定義設定

/**
 * 功能描述:
 *
 * @author liuchaoyong
 * @version 1.0
 * @date 2019-05-26 21:41
 */
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
 
    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024));
            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
        });
    }
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。 


IT145.com E-mail:sddin#qq.com