1693 字
约 5 分钟
1
🚀 SpringBoot Tomcat部署
2026-09-19
无标签

🚀 第12章 SpringBoot Tomcat部署

掌握SpringBoot应用的Tomcat部署策略与优化技巧 💻 查看完整代码 - 在线IDE体验 学习目标

📋 学习目标

  • 掌握部署方式- JAR包与WAR包部署
  • 了解Tomcat配置- 内嵌与外部Tomcat
  • 学会性能优化- 连接池与JVM调优
  • 掌握监控技巧- 应用状态监控
  • 了解安全配置- HTTPS与安全策略
  • 学会故障排查- 日志分析与调试

部署方式

📦 部署方式

  • JAR包部署- 内嵌Tomcat,独立运行
  • WAR包部署- 外部Tomcat容器
  • Docker部署- 容器化部署
  • 云平台部署- 云服务器部署
  • 集群部署- 负载均衡部署
  • 蓝绿部署- 零停机部署

JAR包部署配置

📦 JAR包部署配置

<!-- pom.xml JAR包配置 -->
<project>
    <groupId>cn.bugstack.springframework.boot</groupId>
    <artifactId>chapter-12-tomcat</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <dependencies>
        <!-- SpringBoot Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- SpringBoot Actuator监控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- SpringBoot Maven插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

# application.yml JAR包配置
server:
  port: 8080
  servlet:
    context-path: /api
  tomcat:
    # 连接器配置
    max-connections: 8192
    accept-count: 100
    max-threads: 200
    min-spare-threads: 10
    # 连接超时
    connection-timeout: 20000
    # 压缩配置
    compression:
      enabled: true
      mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
      min-response-size: 1024

# 启动脚本 start.sh
#!/bin/bash
APP_NAME="chapter-12-tomcat"
JAR_NAME="$APP_NAME-1.0-SNAPSHOT.jar"
PID_FILE="$APP_NAME.pid"

# JVM参数配置
JVM_OPTS="-Xms512m -Xmx1024m"
JVM_OPTS="$JVM_OPTS -XX:+UseG1GC"
JVM_OPTS="$JVM_OPTS -XX:MaxGCPauseMillis=200"
JVM_OPTS="$JVM_OPTS -XX:+PrintGCDetails"
JVM_OPTS="$JVM_OPTS -Xloggc:gc.log"

# 启动应用
nohup java $JVM_OPTS -jar $JAR_NAME > app.log 2>&1 &
echo $! > $PID_FILE
echo "应用启动成功,PID: $(cat $PID_FILE)"

部署流程

🔄 部署流程

1代码构建 使用Maven或Gradle构建JAR/WAR包 2环境准备 配置服务器环境,安装JDK和Tomcat 3应用部署 上传应用包,配置启动脚本 4服务启动 启动应用服务,验证运行状态 5监控验证 检查应用健康状态,配置监控告警 WAR包部署配置

📁 WAR包部署配置

<!-- pom.xml WAR包配置 -->
<project>
    <packaging>war</packaging>
    
    <dependencies>
        <!-- SpringBoot Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- 排除内嵌Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

// SpringBootServletInitializer.java
@SpringBootApplication
public class TomcatApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TomcatApplication.class);
    }
    
    public static void main(String[] args) {
        SpringApplication.run(TomcatApplication.class, args);
    }
}

<!-- Tomcat server.xml 配置 -->
<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <!-- HTTP连接器 -->
        <Connector port="8080" 
                   protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   maxThreads="200"
                   minSpareThreads="10"
                   maxConnections="8192"
                   acceptCount="100"
                   compression="on"
                   compressionMinSize="1024"
                   compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"
                   redirectPort="8443" />
        
        <!-- HTTPS连接器 -->
        <Connector port="8443" 
                   protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" 
                   SSLEnabled="true"
                   scheme="https" 
                   secure="true"
                   clientAuth="false" 
                   sslProtocol="TLS"
                   keystoreFile="conf/keystore.jks"
                   keystorePass="password" />
        
        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" 
                  appBase="webapps"
                  unpackWARs="true" 
                  autoDeploy="true">
                
                <!-- 应用上下文配置 -->
                <Context path="/api" 
                         docBase="chapter-12-tomcat.war"
                         reloadable="false">
                    <!-- 数据源配置 -->
                    <Resource name="jdbc/dataSource"
                              auth="Container"
                              type="javax.sql.DataSource"
                              maxTotal="20"
                              maxIdle="10"
                              maxWaitMillis="10000"
                              username="root"
                              password="password"
                              driverClassName="com.mysql.cj.jdbc.Driver"
                              url="jdbc:mysql://localhost:3306/springboot" />
                </Context>
            </Host>
        </Engine>
    </Service>
</Server>

# Tomcat启动脚本 catalina.sh
export JAVA_OPTS="-Xms1024m -Xmx2048m"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"
export JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=200"
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod"
export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"

Tomcat优化配置

⚡ Tomcat优化

  • 连接器优化- 线程池与连接数
  • 内存优化- JVM堆内存配置
  • GC优化- 垃圾回收器选择
  • 压缩配置- HTTP响应压缩
  • 缓存策略- 静态资源缓存
  • 安全配置- 安全头与过滤器

监控与运维

📊 监控运维

  • 健康检查- Actuator端点监控
  • 性能监控- JVM与应用指标
  • 日志管理- 日志收集与分析
  • 告警配置- 异常状态告警
  • 备份策略- 数据与配置备份
  • 故障恢复- 快速故障恢复

性能优化配置

⚡ 性能优化配置

# application-prod.yml 生产环境配置
server:
  tomcat:
    # 线程配置
    max-threads: 200
    min-spare-threads: 20
    max-connections: 8192
    accept-count: 100
    
    # 连接超时配置
    connection-timeout: 20000
    keep-alive-timeout: 60000
    max-keep-alive-requests: 100
    
    # 压缩配置
    compression:
      enabled: true
      mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml
      min-response-size: 1024
    
    # 访问日志配置
    accesslog:
      enabled: true
      directory: logs
      file-date-format: .yyyy-MM-dd
      pattern: '%t %a "%r" %s (%D ms)'
      
  # HTTP/2支持
  http2:
    enabled: true

# JVM优化参数
# -Xms2g -Xmx4g
# -XX:+UseG1GC
# -XX:MaxGCPauseMillis=200
# -XX:+UseStringDeduplication
# -XX:+PrintGCDetails
# -XX:+PrintGCTimeStamps
# -Xloggc:gc.log

# 连接池配置
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 60000

# 缓存配置
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=1000,expireAfterWrite=5m

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true

// TomcatCustomizer.java - Tomcat自定义配置
@Component
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // 自定义连接器
        factory.addConnectorCustomizers(connector -> {
            Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
            
            // 设置最大线程数
            protocol.setMaxThreads(200);
            protocol.setMinSpareThreads(20);
            
            // 设置连接超时
            protocol.setConnectionTimeout(20000);
            protocol.setKeepAliveTimeout(60000);
            
            // 启用压缩
            protocol.setCompression("on");
            protocol.setCompressionMinSize(1024);
            
            // 设置最大连接数
            protocol.setMaxConnections(8192);
            protocol.setAcceptCount(100);
        });
        
        // 添加错误页面
        factory.addErrorPages(
            new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"),
            new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500")
        );
        
        // 设置会话超时
        factory.addInitializers(servletContext -> {
            servletContext.getSessionCookieConfig().setMaxAge(30 * 60); // 30分钟
        });
    }
}

// PerformanceFilter.java - 性能监控过滤器
@Component
@Order(1)
public class PerformanceFilter implements Filter {
    
    private static final Logger logger = LoggerFactory.getLogger(PerformanceFilter.class);
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        long startTime = System.currentTimeMillis();
        
        try {
            chain.doFilter(request, response);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            
            // 记录慢请求
            if (duration > 1000) {
                logger.warn("慢请求: {} {} 耗时: {}ms", 
                    httpRequest.getMethod(), 
                    httpRequest.getRequestURI(), 
                    duration);
            }
            
            // 记录性能指标
            Metrics.timer("http.request.duration", 
                "method", httpRequest.getMethod(),
                "uri", httpRequest.getRequestURI())
                .record(duration, TimeUnit.MILLISECONDS);
        }
    }
}

部署对比表

📊 部署方式对比

部署方式 优点 缺点 适用场景
JAR包部署 简单快速、内嵌容器、独立运行 资源占用较高、升级需重启 微服务、云原生应用
WAR包部署 资源共享、统一管理、热部署 配置复杂、容器依赖 传统企业应用
Docker部署 环境一致、易扩展、版本管理 学习成本、资源开销 容器化环境
云平台部署 弹性伸缩、高可用、托管服务 成本较高、厂商绑定 大规模应用

故障排查

🔧 故障排查

🚨 常见问题与解决方案启动失败- 检查端口占用、配置文件、依赖冲突内存溢出- 调整JVM参数、优化代码、增加内存响应缓慢- 分析线程池、数据库连接、网络延迟连接超时- 检查网络配置、防火墙、负载均衡日志异常- 查看错误日志、堆栈信息、系统资源

# 故障排查命令
# 1. 检查应用进程
ps aux | grep java

# 2. 检查端口占用
netstat -tlnp | grep 8080
lsof -i :8080

# 3. 查看JVM信息
jps -l
jinfo <pid>
jstat -gc <pid> 1s

# 4. 生成堆转储
jmap -dump:format=b,file=heapdump.hprof <pid>

# 5. 查看线程信息
jstack <pid>

# 6. 监控系统资源
top -p <pid>
iostat 1
free -h

# 7. 查看应用日志
tail -f application.log
grep ERROR application.log
grep -A 10 -B 10 "OutOfMemoryError" application.log

# 8. 网络诊断
ping <host>
telnet <host> <port>
curl -I http://localhost:8080/actuator/health

下一章节

🎉 恭喜完成第13章学习!

你已经掌握了SpringBoot Tomcat部署的核心技能,接下来学习AOP切面编程! 🎯 下一章:SpringBoot AOP ⬅️ 返回第12章 🏠 返回课程首页

🚀 SpringBoot Tomcat部署
http://www.clxhxhhr.top/posts/2881/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。