🚀 第12章 SpringBoot Tomcat部署

掌握SpringBoot应用的Tomcat部署策略与优化技巧

💻 查看完整代码 - 在线IDE体验

📋 学习目标

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

📦 部署方式

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

📦 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包部署配置

<!-- 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优化

  • 连接器优化 - 线程池与连接数
  • 内存优化 - 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章 🏠 返回课程首页