Spring Boot 核心理解-嵌入式服务器

在 Spring Boot 中,嵌入式服务器(如 Tomcat、Jetty 等)是应用的一个重要特性。它允许 Spring Boot 应用以自包含的方式运行,而无需依赖外部的应用服务器。了解嵌入式服务器的原理、如何定制它们,以及在需要时如何替换服务器,可以帮助开发人员更灵活地部署和配置 Spring Boot 应用。

1. 什么是嵌入式服务器?

嵌入式服务器指的是 Spring Boot 应用在打包时,将服务器(如 Tomcat、Jetty 或 Undertow)作为依赖一并打包在应用中。因此,应用程序可以独立运行,不依赖于外部的应用服务器容器。

例如,Spring Boot 默认使用嵌入式 Tomcat。当你运行 Spring Boot 应用时,它会自动启动一个内置的 Tomcat 服务器并将应用部署到这个服务器上。这种模式使得部署和启动变得非常简单,只需要一个可执行的 JAR 文件即可运行。

2. 如何定制嵌入式服务器?

Spring Boot 提供了多种方式来定制嵌入式服务器的配置。常见的定制内容包括服务器端口、上下文路径、最大线程数等。

2.1 定制常见的服务器参数

你可以在 application.propertiesapplication.yml 中定制服务器的常见配置:

使用 application.properties

bash 复制代码
server.port=8081           # 改变默认端口号
server.servlet.context-path=/myapp   # 修改应用的上下文路径
server.tomcat.max-threads=200  # 配置 Tomcat 最大线程数

2.2 使用 TomcatServletWebServerFactory 自定义配置

如果需要更细致的控制,可以定义一个 @Bean 来使用 TomcatServletWebServerFactory

java 复制代码
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomTomcatConfig {

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> customizer() {
        return factory -> {
            factory.setPort(8082);  // 修改端口
            factory.setContextPath("/custom");  // 修改上下文路径
            factory.setSessionTimeout(30);  // 设置会话超时时间(分钟)
        };
    }
}

通过这种方式,你可以以编程的方式更加灵活地定制 Tomcat 的各种参数。

3. 替换嵌入式服务器

Spring Boot 默认使用 Tomcat,但在某些场景下,可能需要使用其他服务器如 Jetty 或 Undertow。替换嵌入式服务器非常简单,只需修改 Maven 或 Gradle 的依赖配置即可。

3.1 使用 Jetty

pom.xml 中排除 Tomcat 并添加 Jetty 依赖:

XML 复制代码
<dependencies>
    <!-- 排除默认的 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>

    <!-- 添加 Jetty 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
</dependencies>

这样,Spring Boot 就会使用嵌入式 Jetty 服务器来替代默认的 Tomcat。

3.2 使用 Undertow

类似地,如果需要使用 Undertow,可以在 pom.xml 中添加以下配置:

XML 复制代码
<dependencies>
    <!-- 排除默认的 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>

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

这将会让 Spring Boot 使用 Undertow 作为嵌入式服务器。

4.为什么选择嵌入式服务器?

嵌入式服务器的优势在于:

  • 简化部署:无需安装和配置外部应用服务器,应用程序可以通过一个可执行的 JAR 文件独立运行。
  • 环境一致性:开发、测试和生产环境可以使用完全相同的服务器配置,减少了因环境差异带来的问题。
  • 自动化部署:方便与 CI/CD 流程集成,适合云原生架构和容器化部署。

5. 示例总结

嵌入式服务器让 Spring Boot 应用能够以独立的方式运行,并且通过简单的配置或编程方式定制服务器行为。如果你希望在开发和测试环境中快速启动一个应用,并且对部署环境没有特殊的依赖,那么嵌入式服务器是一个非常好的选择。

例如,要更改默认的 Tomcat 端口号,只需要在 application.properties 中配置 server.port=8081,或者在代码中通过 TomcatServletWebServerFactory 定制。如果需要使用 Jetty,只需调整 Maven 依赖。通过这些方式,你可以根据不同的需求选择最适合的嵌入式服务器。

写在最后:嵌入式服务器的选择依据

选择嵌入式服务器时,主要需要考虑应用的特性、运行环境以及性能需求。以下是选择嵌入式服务器时常用的几个标准和推荐场景:

1. 性能需求

不同的嵌入式服务器在性能和特性上有所差异:

  • Tomcat:适合大多数标准的 Web 应用,是 Spring Boot 的默认选择。它在处理 HTTP 请求方面表现稳定,尤其是处理阻塞 I/O 时。

    • 适合场景:标准的 RESTful API、MVC 应用,支持 Servlet 规范的功能较为全面。
    • 优势:社区成熟,使用广泛,文档和支持丰富。
  • Jetty:相比 Tomcat 更加轻量,启动速度更快,适合需要快速启动和高并发的场景。Jetty 的非阻塞 I/O 使其在处理大量并发连接时更加高效。

    • 适合场景:需要快速启动的微服务、嵌入式设备、处理大量 WebSocket 连接的应用。
    • 优势:启动快,非阻塞 I/O 性能好,适用于高并发应用。
  • Undertow:一个高性能、低内存占用的服务器,支持完全异步的非阻塞模式,性能非常高。它是 WildFly(前 JBoss 应用服务器)的默认 Web 服务器。

    • 适合场景:微服务、需要高吞吐量和低延迟的系统,或对异步 I/O 支持有较高要求的应用。
    • 优势:性能优于 Tomcat 和 Jetty,支持 WebSocket 和 HTTP/2,适合高性能和非阻塞应用。

2. 应用类型

不同类型的应用对服务器的支持也有不同的要求:

  • 传统的 MVC 应用:Tomcat 通常是首选,因为它支持 Servlet 和 JSP,并且在大多数场景下性能足够。
  • 需要大量 WebSocket 支持:Jetty 和 Undertow 通常比 Tomcat 表现更好。Jetty 原生支持 WebSocket,并且性能出色。
  • 异步和非阻塞应用:如果应用有大量非阻塞操作,Undertow 是一个很好的选择。它的非阻塞特性和高吞吐量使得它特别适合处理高并发的请求。

3. 部署环境

  • 容器化和微服务架构:Jetty 和 Undertow 更适合微服务和容器化部署。它们轻量、启动快,可以减少容器启动和部署时间。
  • 嵌入式设备或资源受限的环境:Jetty 和 Undertow 比 Tomcat 更轻量,可以节省内存和 CPU 资源。

4. 开发团队的经验

开发团队对特定服务器的熟悉度也是一个重要考虑因素:

  • 如果团队成员已经对 Tomcat 非常熟悉,并且当前应用性能足够,那么继续使用 Tomcat 是一个明智的选择。
  • 如果团队熟悉 JBoss 或 WildFly 生态,Undertow 会是更自然的选择。
  • 对 Jetty 有经验的团队,可能会倾向选择它来获得更好的启动速度和更灵活的配置选项。

5. 功能特性

  • 需要支持 HTTP/2:Undertow 和 Jetty 对 HTTP/2 支持更好。如果你的应用需要使用 HTTP/2 来提高客户端和服务器之间的性能,可以优先考虑这两者。
  • 定制化需求:如果有定制需求(例如自定义连接器、特殊的 SSL 配置),Jetty 通常比 Tomcat 提供更灵活的扩展接口。

6. 社区和生态支持

  • 社区支持:Tomcat 是最成熟、使用最广泛的嵌入式服务器,很多问题都可以在社区中找到解决方案。如果项目需要长期维护和稳定性保障,选择 Tomcat 可能会更有优势。
  • 生态和文档:Jetty 和 Undertow 也有良好的文档和活跃的社区支持,适合对性能有更高要求的项目。

总结

选择嵌入式服务器时,最主要的考量因素包括应用的性能需求、类型、部署环境、团队经验、以及功能特性。Tomcat 适合大多数标准场景,Jetty 更加灵活且适合高并发,Undertow 则在性能上更优异。如果项目对性能和启动速度要求特别高,可以考虑 Jetty 或 Undertow,而如果希望稳定且广泛的支持,则可以继续使用 Tomcat。

相关推荐
wno7045 分钟前
Spring Boot配合Hibernate Validator参数校验
spring boot·后端·hibernate
赵庆明老师26 分钟前
用同一个用户登录宝塔面板的ftp与Linux的sftp
linux·运维·服务器
astronautyi28 分钟前
Go 运行时内存分配与 GC 位图深度剖析
开发语言·后端·golang
techdashen35 分钟前
Go 中如何处理错误
开发语言·后端·golang
山君爱摸鱼44 分钟前
堡垒机远程服务器故障收集
运维·服务器
GoGeekBaird1 小时前
Agent 时代,你的生产环境,真的敢让它裸奔吗
后端·agent
IT_陈寒1 小时前
Redis Pipeline用错竟比不用还慢,这个坑我帮你踩过了
前端·人工智能·后端
名字还没想好☜1 小时前
Go 1.21 context.WithoutCancel 实战:父 context 取消了,收尾任务还要继续跑
开发语言·后端·golang·go
比兔代理2 小时前
住宅代理IP的出口节点调度:ASN、BGP 与 IP 段信誉机制解析
linux·服务器·网络
源代码•宸2 小时前
前置准备:定时微服务有什么价值
经验分享·后端·微服务·云原生·架构