在传统Java Web开发中,部署WAR包到外部Web服务器的流程复杂且低效。Spring Boot通过**嵌入式服务器(Embedded Server)**机制彻底改变了这一现状,使得应用打包即包含完整运行时环境。本文将深入剖析Spring Boot嵌入式服务器的技术原理,并通过实战案例演示各种进阶配置技巧。
特性 | Tomcat | Jetty | Undertow |
---|---|---|---|
默认版本 | 10.x | 11.x | 2.x |
内存占用 | 中等 | 较低 | 最低 |
吞吐量 | 优秀 | 良好 | 卓越 |
异步支持 | Servlet 3.1+ | 原生异步IO | 基于XNIO |
WebSocket性能 | 标准实现 | 高性能 | 最佳性能 |
适用场景 | 传统Web应用 | 高并发长连接 | 资源敏感型应用 |
# application.properties
# 服务器基础配置
server.port=8080
server.servlet.context-path=/api
server.connection-timeout=30s
# Tomcat专属配置
server.tomcat.max-threads=200
server.tomcat.accept-count=100
server.tomcat.uri-encoding=UTF-8
# Undertow专属配置
server.undertow.io-threads=16
server.undertow.worker-threads=64
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addAdditionalTomcatConnectors(createSslConnector());
return factory;
}
private Connector createSslConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
File keystore = new ClassPathResource("keystore.jks").getFile();
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.getAbsolutePath());
protocol.setKeystorePass("changeit");
protocol.setKeyAlias("tomcat");
return connector;
} catch (Exception ex) {
throw new IllegalStateException("SSL配置失败", ex);
}
}
# application.yml
server:
tomcat:
threads:
max: 500 # 最大工作线程数
min-spare: 50 # 最小空闲线程
connection-timeout: 5000ms
max-connections: 10000
accept-count: 500 # 等待队列长度
# 启用GZIP压缩
server.compression.enabled=true
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/json
server.compression.min-response-size=1024
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
AccessLogValve valve = new AccessLogValve();
valve.setPattern("%t %a %r %s (%D ms)");
valve.setDirectory("logs");
valve.setSuffix(".access.log");
context.getPipeline().addValve(valve);
}
};
}
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-undertowartifactId>
dependency>
dependencies>
# Undertow高级参数
server.undertow.buffer-size=1024
server.undertow.direct-buffers=true
server.undertow.eager-filter-init=true
server.undertow.max-http-post-size=10MB
# 启用健康检查端点
management.endpoints.web.exposure.include=health,metrics
management.endpoint.health.show-details=always
# 自定义健康指标
@Component
public class ServerHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// 检查服务器状态
return Health.up().withDetail("activeSessions", 42).build();
}
}
@Bean
public MeterRegistryCustomizer<PrometheusMeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags(
"application", "spring-boot-server",
"container", "embedded-tomcat"
);
}
内存限制策略
JVM参数建议配置:
-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m
优雅停机配置
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
连接池优化
spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
idle-timeout: 600000
容器版本管理
在pom.xml中显式指定容器版本:
<properties>
<tomcat.version>10.0.27tomcat.version>
properties>
# Linux/Mac查询端口占用
lsof -i :8080
# Windows查询端口占用
netstat -ano | findstr :8080
@RestController
public class MemDebugController {
@GetMapping("/heapdump")
public void getHeapDump(HttpServletResponse response) throws IOException {
HeapDumper.dumpHeap("heap.hprof", true);
FileCopyUtils.copy(new FileInputStream("heap.hprof"), response.getOutputStream());
}
}
Spring Boot嵌入式服务器的优势: