優化背景
當你的application需要支持瞬時高并發的時候,tomcat已經不在是最優的選擇,我們可以改為Undertow,并對其進行優化。
Undertow 是一個輕量級的、高性能的Java Web 服務器,由JBoss 開發并開源。它是基于非阻塞(non-blocking)的I/O模型,具有低資源消耗和高并發處理能力。
SpringBoot3如何從tomcat改為undertow
需要在pom.xml
中排除Tomcat,并添加Undertow的依賴:
<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
?或?application.properties
?中添加以下配置:
server:undertow:# 線程池配置threads:# I/O線程數(建議設置為CPU核心數的1-2倍)io: 16# 工作線程數(建議設置為CPU核心數的8-16倍)worker: 256# 緩沖池配置buffer-size: 1024# 是否直接使用內存作為緩沖區direct-buffers: true
限制接口超時時間
server:undertow:# 請求超時設置(毫秒)no-request-timeout: 30000# 連接空閑超時(毫秒)idle-timeout: 60000
限制請求體大小不超過2KB
server:undertow:# 限制HTTP POST請求體大小(2KB=2048字節)max-http-post-size: 2048
請求壓縮配置
SpringBoot的server compression功能用于減少響應數據的大小,從而提高傳輸效率,減少帶寬占用,加快頁面加載速度。它通常使用Gzip或Deflate等壓縮算法來優化HTTP響應。
作用
-
減少數據傳輸量:壓縮后數據體積更小,降低網絡開銷。
-
提高加載速度:特別適用于前端頁面、API接口等場景。
-
降低服務器負載:減少數據傳輸時間,提高服務器吞吐量。
-
優化用戶體驗:頁面加載更快,提升訪問流暢度。
推薦配置
在SpringBoot的application.yml
或application.properties
中啟用壓縮:
server:compression:enabled: true # 開啟壓縮min-response-size: 1024 # 觸發壓縮的最小響應大小(默認2KB)mime-types: application/json, text/html, text/xml, text/plain, text/css, application/javascript # 需要壓縮的內容類型excluded-user-agents: IE6, IE7 # 排除舊版瀏覽器
啟用HTTP/2 (需要SSL支持)
server:http2:enabled: true
Undertow 訪問日志配置
server:undertow:accesslog:enabled: truedir: ./logsprefix: access_log.suffix: .logpattern: '%t %a "%r" %s (%D ms)'rotate: true
監控與調優建議
-
監控線程池狀態:通過JMX或Actuator監控線程池使用情況
-
壓力測試:使用JMeter或wrk進行負載測試,觀察線程池表現
-
JVM調優:根據負載情況調整JVM堆內存和GC參數
-
連接池調優:如果使用數據庫,確保連接池配置與服務器線程數匹配 (SpringBoot3 + Druid + DynamicDataSource + PgSQL 連接池優化方案-CSDN博客)
附錄:Undertow配置屬性
Spring Boot 預置了很多屬性,可用于在?applicaton.properties | yaml
?中對 Undertow 服務器進行個性化配置。
它們都以?server.undertow.*
?開頭,總結如下:
配置項 | 說明 | 示例 |
---|---|---|
server.undertow.accesslog.dir | Undertow 訪問日志目錄。 | |
server.undertow.accesslog.enabled | 是否啟用訪問日志。 | false |
server.undertow.accesslog.pattern | 訪問日志的格式。 | common |
server.undertow.accesslog.prefix | 日志文件前綴。 | access_log. |
server.undertow.accesslog.rotate | 是否開啟日志滾動。 | true |
server.undertow.accesslog.suffix | 日志文件后綴。 | log |
server.undertow.always-set-keep-alive | 是否應在所有響應中添加?Connection: keep-alive ?Header,即使 HTTP 規范沒有要求。 | true |
server.undertow.buffer-size | 每個 buffer 的大小。默認大小是根據 JVM 可用的最大內存確定的。 | |
server.undertow.decode-slash | 是否應解碼已編碼的斜線字符(%2F )。如果前端代理不執行相同的解碼,解碼可能會導致安全問題。只有在傳統應用程序需要時才啟用。設置后,server.undertow.allow-encoded-slash ?無效。 | |
server.undertow.decode-url | 是否對 URL 進行解碼。禁用時,URL 中的百分比編碼字符將保持原樣。 | true |
server.undertow.direct-buffers | 是否在 Java 堆外分配 buffer。默認大小是根據 JVM 可用的最大內存確定的。 | |
server.undertow.eager-filter-init | 是否應在啟動時初始化 servlet Filter | true |
server.undertow.max-cookies | 允許的最大 cookie 數量。這一限制是為了防止基于哈希碰撞的 DOS 攻擊。 | 200 |
server.undertow.max-headers | 允許的最大 header 數量。這一限制是為了防止基于哈希碰撞的 DOS 攻擊。 | |
server.undertow.max-http-post-size | HTTP post content 的最大大小。當值為-1(默認值)時,大小為無限。 | -1B |
server.undertow.max-parameters | 允許查詢或路徑參數的最大數量。這一限制是為了防止基于哈希碰撞的 DOS 攻擊。 | |
server.undertow.no-request-timeout | 在服務器關閉連接之前,連接在不處理請求的情況下閑置的時間。 | |
server.undertow.options.server.* | 在?io.undertow.UndertowOptions ?中定義的服務器選項。 | |
server.undertow.options.socket.* | 在?org.xnio.Options ?中定義的 socket 選項。 | |
server.undertow.preserve-path-on-forward | 轉發請求時是否保留請求路徑。 | false |
server.undertow.threads.io | I/O 線程數。默認值為可用的處理器數量。 | |
server.undertow.threads.worker | Worker 線程數。默認為 I/O 線程數的 8 倍。 | |
server.undertow.url-charset | 用于解碼 URL 的字符集。 | UTF-8 |