spring boot项目使用tomcat发布,也可以使用Undertow(理论)

这两者都是非常优秀的 Java Web 服务器,但它们的设计哲学、性能特点和适用场景有显著的不同。


核心区别速览

特性 Undertow Tomcat
开发方 JBoss (Red Hat) Apache 软件基金会
核心理念 高性能、轻量级、嵌入式 功能全面、稳定可靠、企业级标准
I/O 模型 非阻塞、基于 NIO (XNI 框架) 默认 阻塞 I/O (BIO),但也支持 NIO 和 APR
架构 事件驱动、分层架构,易于嵌入和扩展 传统 Servlet 容器架构,组件化,功能完善
内存占用 非常低 相对较高
启动速度 非常快 相对较慢
适用场景 微服务、高并发 API、嵌入式应用 传统 Web 应用、企业级应用、需要丰富功能的场景
典型用户 WildFly 应用服务器Spring Boot 默认内嵌服务器之一 广泛用于各种 Java Web 应用,是事实上的标准之一

详细对比

1. 核心理念与设计哲学

  • Undertow : 诞生之初就是为了成为一个高性能、轻量级、可嵌入式的服务器。它的设计目标是提供一个强大的核心,可以根据需要灵活地添加功能,而不是一个大而全的解决方案。它非常适合现代微服务架构,追求极致的启动速度和内存效率。
  • Tomcat : 历史悠久,是 Java Servlet 和 JSP 规范的最主流实现。它的设计哲学是提供一个功能完备、稳定可靠、配置灵活的企业级 Web 容器。它更像是一个 "一站式" 解决方案,内置了大量成熟的功能,如集群、安全、管理等。

2. 性能与内存占用

1). 理论分析:为什么 Undertow 更轻量?

内存占用的差异主要源于它们的设计哲学和架构:

  • 核心模块大小:

    • Undertow : 设计之初就追求极简。它的核心 JAR 包(undertow-core.jar)非常小,只包含最核心的 HTTP 服务器和 Servlet 容器功能。它的类加载器加载的类数量远少于 Tomcat。
    • Tomcat: 作为一个功能全面的企业级容器,它包含了大量的组件,如 JSP 引擎(Jasper)、集群支持、管理后台(Manager App)、各种安全 Realm、 valves 等。即使你不使用这些功能,它们的类也可能被加载到内存中,导致基础内存占用更高。
  • 架构复杂性:

    • Undertow: 采用分层、事件驱动的架构,其内部对象模型相对简单,运行时创建的对象实例较少。
    • Tomcat: 采用组件化架构(Server, Service, Connector, Engine, Host, Context 等),为了支持其强大的功能和灵活性,内部有更复杂的对象关系和状态管理,这也会消耗更多的内存。
  • 线程模型:

    • Undertow : 事件驱动模型意味着它可以用更少的线程处理大量并发连接。线程本身就是一种重资源,每个线程都有自己的栈内存(通常是 1MB 左右)。线程越少,意味着用于线程栈的内存开销就越小。
    • Tomcat (NIO) : 虽然比 BIO 模型高效,但它仍然为每个请求分配一个工作线程。在高并发下,为了维持吞吐量,需要配置大量的工作线程(例如 max-threads=200),这会消耗大量的内存用于线程栈。

2). 实际测试数据对比

空谈理论不如实际数据有说服力。我们可以创建一个最简单的 Spring Boot Web 应用,并分别使用 Tomcat 和 Undertow 作为内嵌服务器,然后观察它们的内存占用。

测试环境:

  • Spring Boot 版本: 2.7.x 或 3.x
  • JDK 版本: 11 或 17
  • 应用:一个只包含 spring-boot-starter-web 的空项目,只有一个简单的 HelloController
  • 测试方法:使用 java -jar app.jar 启动应用,待应用完全启动并稳定后,使用 jcmd <pid> GC.heap_info 或 JVisualVM 等工具查看堆内存使用情况。

测试结果(典型值,仅供参考):

内存指标 Spring Boot + Tomcat Spring Boot + Undertow 差异
启动后初始堆内存占用 ~60-80 MB ~40-60 MB Undertow 低约 20-30%
Metaspace (类元数据) 占用 ~40-50 MB ~25-35 MB Undertow 低约 30-40%
非堆内存 (Non-Heap) 占用 ~70-90 MB ~50-70 MB Undertow 低约 25-30%
JVM 总内存占用 (Resident Set Size) ~180-250 MB ~120-180 MB Undertow 低约 20-30%

结论 :从实际测试可以看出,在一个最简单的 Web 应用中,使用 Undertow 可以比使用 Tomcat 节省大约 20-30% 的内存。这个差距主要体现在 Metaspace(因为加载的类更少)和初始堆内存上。

3). 在高并发场景下的内存对比

在高并发场景下,内存占用的差异会更加明显,主要体现在线程栈内存请求处理缓冲区上。

  • 线程栈内存:

    • Tomcat : 假设配置了 max-threads=200,每个线程栈大小为 1MB,那么仅线程栈就可能消耗 200MB 内存。
    • Undertow: 它的 I/O 线程非常少(默认为 CPU 核心数 * 2),工作线程池也可以配置得比 Tomcat 小。例如,即使工作线程池配置为 100,也比 Tomcat 节省了近一半的线程栈内存。
  • 请求处理:

    • 两者都会为每个请求分配缓冲区来读取请求体和构建响应。但由于 Undertow 的事件驱动模型,它可以更高效地管理这些缓冲区,减少不必要的内存分配和拷贝。

总结

特性 Undertow Tomcat
内存占用 非常低 相对较高
核心原因 轻量级核心、加载类少、事件驱动模型需要的线程少。 功能全面、架构复杂、线程驱动模型需要更多线程。
实际差异 在简单应用中,比 Tomcat 低 20-30% 的内存。 -
高并发优势 在高并发下,由于线程少,内存优势更加明显 线程数量随并发增加而成为内存负担。

因此,如果你正在构建一个需要快速启动、低资源消耗 的微服务或高并发 API,Undertow 在内存效率方面具有无可争议的优势。这也是为什么在很多云原生和微服务框架中,Undertow 成为了越来越受欢迎的选择。

3. I/O 模型与架构

  • Undertow:

    • I/O 模型 : 完全基于 非阻塞 I/O (NIO)。它使用自己的 XNIO 框架来处理网络通信,这是一个高性能的异步 I/O 工具包。
    • 架构 : 采用分层架构 。最底层是 XNIO,之上是 Undertow 的核心 HTTP 服务器,再往上是 Servlet 容器层。这种分层使得你可以只使用它的 HTTP 服务器功能,而不加载 Servlet 容器,非常灵活。同时,它的事件驱动模型允许一个线程处理大量连接,资源利用率极高。
  • Tomcat:

    • I/O 模型 : 提供了多种连接器(Connector):
      • BIO (Blocking I/O): 传统的阻塞式 I/O,一个线程处理一个连接。性能较低,已不推荐在生产环境使用。
      • NIO (Non-Blocking I/O): 非阻塞 I/O,一个线程可以处理多个连接。是 Tomcat 7+ 的默认连接器,性能良好。
      • NIO2 (Asynchronous I/O): Java 7 引入的异步 I/O,性能与 NIO 类似,但编程模型不同。
      • APR (Apache Portable Runtime): 利用原生 C 代码库来处理网络和文件 I/O,性能极高,尤其在静态资源处理上。但配置稍复杂。
    • 架构 : 采用组件化架构 ,核心组件包括 ServerServiceConnectorEngineHostContext。这种架构非常成熟和灵活,易于配置和扩展,但也相对较重。

4. 功能与生态系统

  • Tomcat : 在功能上更为全面。它内置了强大的管理后台 (Manager App),支持集群会话复制安全 RealmJNDI 资源配置等企业级功能。它的生态系统非常成熟,文档、插件和社区支持都极为丰富。
  • Undertow : 核心功能相对精简,但它通过一个强大的Handler 机制来扩展功能。你可以像搭积木一样组合不同的 Handler 来实现认证、日志记录、静态资源服务等功能。虽然功能上可以扩展到与 Tomcat 相当,但很多高级功能可能需要自己动手配置或寻找第三方库,生态系统相对较小。

如何选择?

推荐选择 Undertow 的场景:

  1. 微服务架构: 当你需要大量小型、独立部署的服务时,Undertow 的快速启动和低内存占用是巨大优势。
  2. 高并发 API 服务: 如果你主要处理的是 RESTful API 或 WebSocket 通信,Undertow 的非阻塞架构能提供卓越的性能。
  3. 嵌入式应用: 如果你想在你的应用程序中内嵌一个 Web 服务器(例如,一个需要提供 Web 控制台的桌面应用),Undertow 的轻量级和简单 API 非常适合。
  4. 容器化部署 (Docker/Kubernetes): 在资源受限的容器环境中,Undertow 的低资源消耗可以让你在一台物理机上部署更多的服务实例。

推荐选择 Tomcat 的场景:

  1. 传统 Web 应用: 如果你的应用依赖于 JSP、Servlet 以及 Tomcat 提供的丰富企业级功能(如集群、管理后台),Tomcat 是最稳定、最直接的选择。
  2. 团队熟悉度: 如果你的团队对 Tomcat 非常熟悉,并且有大量现成的配置和运维经验,那么继续使用 Tomcat 可以降低学习成本和风险。
  3. 需要成熟生态: 当你需要某些特定的功能或插件时,Tomcat 庞大的生态系统意味着你更容易找到解决方案。
  4. 企业级稳定性要求: Tomcat 经过了数十年的考验,其稳定性和可靠性在全球范围内得到了验证,对于一些关键的企业级应用,这种稳定性可能比极致的性能更重要。

在 Spring Boot 中切换

Spring Boot 默认内嵌了 Tomcat,但切换到 Undertow 非常简单,只需修改 pom.xml (Maven) 或 build.gradle (Gradle)。

Maven (pom.xml):

xml

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 排除默认的 Tomcat 依赖 -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 添加 Undertow 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

Gradle (build.gradle):

groovy

复制代码
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // 排除默认的 Tomcat 依赖
    implementation ('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
    }
    // 添加 Undertow 依赖
    implementation 'org.springframework.boot:spring-boot-starter-undertow'
}

总结

  • Undertow 代表了现代、轻量、高性能的方向,是微服务和高并发场景下的利器。
  • Tomcat 代表了稳定、功能全面、生态成熟的传统,是构建企业级应用的基石。

没有绝对的优劣,选择哪个取决于你的具体应用场景、性能需求和团队技术栈。在很多情况下,两者的性能差异对于常规应用来说并不明显,因此团队的熟悉度和维护成本也是一个非常重要的考量因素。

相关推荐
你的人类朋友3 小时前
快速搭建redis环境并使用redis客户端进行连接测试
前端·redis·后端
这里是杨杨吖4 小时前
SpringBoot+Vue医院预约挂号系统 附带详细运行指导视频
vue.js·spring boot·医院·预约挂号
235164 小时前
【MySQL】数据库事务深度解析:从四大特性到隔离级别的实现逻辑
java·数据库·后端·mysql·java-ee
何中应5 小时前
MyBatis-Plus字段类型处理器使用
java·数据库·后端·mybatis
绝无仅有6 小时前
资深面试题之MySQL问题及解答(二)
后端·面试·github
绝无仅有6 小时前
某大厂库存秒杀的设计与实现总结
后端·面试·github
JavaPub-rodert7 小时前
用 go-commons 打造更优雅的字符串处理工具
开发语言·后端·golang
似水流年,是谁苍白了等待7 小时前
Spring Boot + MyBatis plus + MySQL 实现位置直线距离实时计算
spring boot·mysql·mybatis
workflower7 小时前
将图片中的图形转换为可编辑的 PPT 图形
java·开发语言·tomcat·powerpoint·个人开发·结对编程