Tomcat / Undertow / Caddy / IIS 部署指南
Java Web 应用与服务部署涉及多种服务器选型。本文档覆盖传统 Java 应用服务器(Tomcat)、嵌入式容器(Undertow)、轻量级反向代理(Caddy)以及 Windows 平台 IIS 的部署与配置。
Tomcat
Apache Tomcat 是 Java Servlet 容器的事实标准,广泛用于生产环境部署 WAR 包应用。
目录结构
tomcat/
├── bin/ # 启动与关闭脚本
│ ├── startup.sh
│ ├── shutdown.sh
│ ├── catalina.sh # JVM 参数配置入口
│ └── setenv.sh # 环境变量(推荐在此设置 CATALINA_OPTS)
├── conf/ # 配置文件
│ ├── server.xml # 核心:端口、连接器、主机
│ ├── web.xml # 全局 web 配置
│ └── context.xml # 全局 Context 配置
├── logs/ # Catalina.out、localhost.log、access_log
├── webapps/ # 部署 WAR 包的目录
│ ├── ROOT/
│ └── your-app.war
├── work/ # JSP 编译临时文件
└── temp/ # 临时文件部署 WAR 包
将构建后的 WAR 包放入 webapps/ 目录,Tomcat 会自动解压部署。
# 部署方式一:直接复制
cp target/my-app.war /path/to/tomcat/webapps/
# 部署方式二:通过 Manager App(需配置 tomcat-users.xml)
# 自动部署检测:Tomcat 会扫描 webapps/ 目录,新文件会在几秒内部署也可以通过 context.xml 指定外部路径,避免将应用放在 webapps/ 下:
<Context path="/myapp" docBase="/data/apps/my-app" reloadable="false" />server.xml 配置
基础端口与连接器配置
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<!-- 8005 为关闭端口,生产环境建议修改 shutdown 口令 -->
<Service name="Catalina">
<!-- HTTP/1.1 连接器 -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxConnections="10000"
maxThreads="400"
minSpareThreads="50"
acceptCount="200"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"
URIEncoding="UTF-8" />
<!-- AJP 连接器(用于与 Apache/Nginx 配合) -->
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
secretRequired="true"
secret="my-ajp-secret"
maxThreads="400" />
<!-- HTTPS 连接器 -->
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="400"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="/etc/ssl/tomcat/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA" />
</SSLHostConfig>
</Connector>
<Engine name="Catalina" defaultHost="localhost">
<!-- RemoteIpValve:解决反向代理后的真实 IP 问题 -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
proxiesHeader="X-Forwarded-By"
protocolHeader="X-Forwarded-Proto"
internalProxies="10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}"
trustedProxies=".*" />
<!-- Access log -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b %D"
rotatable="true"
fileDateFormat="yyyy-MM-dd" />
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="false">
<Context path="" docBase="my-app" />
</Host>
</Engine>
</Service>
</Server>关键参数说明
| 参数 | 说明 | 推荐值 |
|---|---|---|
maxThreads | 最大工作线程数 | 200-400(视 CPU 核数和业务耗时而定) |
minSpareThreads | 最小空闲线程 | 50 |
acceptCount | 请求队列上限 | 100-200 |
maxConnections | 最大连接数(NIO/NIO2 有效) | 10000 |
connectionTimeout | 连接超时(毫秒) | 20000 |
compression | 是否启用压缩 | on |
JVM 调优
通过 setenv.sh(或 setenv.bat)配置 JVM 参数:
# setenv.sh
JAVA_HOME="/usr/lib/jvm/java-11"
CATALINA_OPTS="-server -Xms4g -Xmx4g -Xmn1g \
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-XX:+ParallelRefProcEnabled \
-XX:+DisableExplicitGC \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/data/dumps \
-Xlog:gc*:/path/to/tomcat/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=10m \
-Dfile.encoding=UTF-8 \
-Djava.security.egd=file:/dev/./urandom"关键调优建议:
- 堆大小:
-Xms与-Xmx设为相同值,避免运行时动态调整。 - 年轻代:
-Xmn设为堆的 25%-40%,根据 GC 日志调整。 - GC 选择:JDK 11+ 优先使用 G1GC;JDK 17+ 可尝试 ZGC(低延迟场景)。
- OOM 处理:务必开启
-XX:+HeapDumpOnOutOfMemoryError并指定 dump 路径。 - 安全随机数:
-Djava.security.egd=file:/dev/./urandom避免 JVM 启动阻塞。
集群配置
Tomcat 支持多种集群方案:
基于 DeltaManager 的 Session 复制
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp"
deployDir="/tmp/war-deploy"
watchDir="/tmp/war-listen"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>生产环境中更推荐使用外置 Session 存储(Redis / Memcached),而非 Tomcat 内置的 Session 复制方案,后者存在广播风暴风险且受带宽约束。
RemoteIpValve 解决真实 IP
当 Tomcat 部署在 Nginx、SLB 或 CDN 之后,request.getRemoteAddr() 获取到的是代理服务器的 IP。通过 RemoteIpValve 可以透传客户端真实 IP:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
internalProxies="10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}"
protocolHeader="X-Forwarded-Proto"
proxiesHeader="X-Forwarded-By" />配置后,应用通过 request.getRemoteAddr() 即可获取客户端真实 IP,request.isSecure() 也会根据 X-Forwarded-Proto 正确返回。
Undertow
Undertow 是 JBoss 出品的轻量级 Web 服务器,作为 Spring Boot 内嵌容器在高并发场景下表现优异。
Spring Boot 内嵌 Undertow
在 pom.xml 中排除 Tomcat 并引入 Undertow:
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>缓冲区与线程池调优
# application.yml
server:
port: 8080
undertow:
# 缓冲区配置
buffer-size: 16384
direct-buffers: true
# 线程池配置
threads:
io: 4 # IO 线程数,通常设为 CPU 核数
worker: 256 # 工作线程数
# HTTP 请求解析选项
max-http-post-size: -1
no-request-timeout: 60000
always-set-keep-alive: true参数说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
buffer-size | 每个缓冲区的字节数,越大则大文件处理越好,但占用更多内存 | 16384 |
direct-buffers | 是否使用堆外内存(减少 GC 压力) | true |
threads.io | IO 线程数,处理连接事件 | CPU 核数 |
threads.worker | 工作线程数,处理业务请求 | 256(根据 QPS 调整) |
Access Log 配置
server:
undertow:
accesslog:
enabled: true
dir: /var/log/undertow
pattern: common
prefix: access_log
suffix: .log
rotate: true支持的 pattern 格式与 Tomcat AccessLogValve 一致。common 等价于 %h %l %u %t "%r" %s %b。也支持自定义:
pattern: "%h %l %u %t \"%r\" %s %b %D %{i,X-Forwarded-For}"编程化配置(高级场景)
import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class UndertowCustomizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
@Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addBuilderCustomizers(builder -> {
builder.setServerOption(UndertowOptions.MAX_HEADER_SIZE, 10240)
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, true)
.setServerOption(UndertowOptions.NO_REQUEST_TIMEOUT, 60000)
.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
});
}
}Caddy
Caddy 是一个 Go 语言编写的 Web 服务器,以自动 HTTPS 和简洁配置著称。
自动 HTTPS(Let's Encrypt)
Caddy 默认启用自动 HTTPS。当配置域名后,它会自动从 Let's Encrypt 申请并续期证书。
example.com {
# Caddy 会自动为 example.com 申请证书
# 无需手动配置 SSL 证书路径
respond "Hello, HTTPS!"
}工作流程:
- Caddy 启动时检测域名配置
- 自动向 Let's Encrypt 申请证书(HTTP-01 或 TLS-ALPN-01 验证)
- 证书存储于
/.caddy/certificates/acme-v02.api.letsencrypt.org-directory/ - 到期前 30 天自动续期
如果需要在本地开发环境禁用 HTTPS:
localhost:8080 {
tls internal # 使用自签名证书
respond "Local dev"
}Caddyfile 配置
反向代理
api.example.com {
# 反向代理到后端 Java 服务
reverse_proxy localhost:8080 {
# 负载均衡:多个后端
# random | round_robin | least_conn | ip_hash
lb_policy round_robin
# 透传真实 IP
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
header_up X-Real-IP {remote_host}
# 健康检查
health_uri /actuator/health
health_interval 30s
health_timeout 5s
health_passes 2
health_fails 3
# 熔断配置
max_fails 5
fail_duration 30s
unhealthy_request_count 10
unhealthy_interval 60s
}
# 日志
log {
output file /var/log/caddy/api.log {
roll_size 100mb
roll_keep 10
roll_keep_days 7
}
format json
}
}静态文件服务
static.example.com {
root * /data/www/static
file_server browse
# 缓存策略
header Cache-Control "max-age=86400"
# Gzip 压缩
encode gzip
# 安全头部
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
}
}多站点与路径路由
# 多站点监听
app1.example.com {
reverse_proxy /api/* localhost:8081
reverse_proxy localhost:8081
}
app2.example.com {
reverse_proxy /api/* localhost:8082
reverse_proxy localhost:8082
}
# 同一域名下路径分流
example.com {
root * /data/web
# API 请求转发到 Java 后端
handle_path /api/* {
reverse_proxy localhost:8080
}
# 静态资源
handle_path /static/* {
root * /data/web/static
file_server
header Cache-Control "max-age=31536000"
}
# 前端 SPA(处理 History 路由)
handle {
try_files {path} /index.html
file_server
}
# 访问日志
log {
output file /var/log/caddy/access.log
}
}与 Nginx 对比
| 维度 | Caddy | Nginx |
|---|---|---|
| 配置文件 | Caddyfile,简洁易读,自动 HTTPS | nginx.conf,功能强大但配置复杂 |
| HTTPS | 自动 Let's Encrypt,零配置 | 需手动配置 certbot + 定时任务续期 |
| 性能 | 与 Nginx 接近,部分静态场景略低 | 极致性能,成熟稳定 |
| 模块/生态 | 插件系统较新,生态较小 | 第三方模块丰富,生态成熟 |
| 动态重载 | 支持 caddy reload,无需中断 | nginx -s reload 热重载 |
| 适用场景 | 中小型项目、团队追求运维简洁 | 大型系统、复杂路由规则、传统运维 |
IIS
Internet Information Services(IIS)是 Windows Server 自带的 Web 服务器。
Windows 部署
启用 IIS
通过 PowerShell 启用 IIS 及必要组件:
# 安装 IIS 核心
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
# 安装 ASP.NET Core 托管组件
# 在 Windows Server 上安装 .NET Hosting Bundle
# 下载地址:https://dotnet.microsoft.com/download/dotnet
# 安装 URL 重写模块(ARR 依赖)
Install-WindowsFeature -Name Web-UrlRewriteASP.NET Core 部署
配置 ASP.NET Core 反向代理到 Kestrel:
<!-- web.config -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*"
modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet"
arguments=".\MyApp.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
<rewrite>
<rules>
<rule name="HTTPS Redirect">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>应用程序池
应用程序池隔离不同站点,提高稳定性和安全性。
配置建议
# 创建新的应用程序池
New-WebAppPool -Name "MyAppPool"
# 设置 .NET CLR 版本(ASP.NET Core 选择 "无托管代码")
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name managedRuntimeVersion -Value ""
# 设置启动模式:AlwaysRunning(避免第一次请求慢)
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name startMode -Value "AlwaysRunning"
# 设置进程模型
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name processModel.idleTimeout -Value "00:00:00"
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name processModel.idleTimeoutAction -Value "Suspend"
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name recycling.periodicRestart.time -Value "00:00:00"
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name recycling.periodicRestart.schedule -Value @()
# 回收配置(避免内存泄漏累积)
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name recycling.periodicRestart.privateMemory -Value 1048576 # 1GB
Set-ItemProperty -Path "IIS:\AppPools\MyAppPool" -Name recycling.periodicRestart.virtualMemory -Value 2097152 # 2GBURL 重写
URL 重写模块用于 SEO 友好 URL、HTTP 跳转等。
<!-- web.config -->
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- HTTP 跳转 HTTPS -->
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
<!-- 域名跳转 -->
<rule name="Canonical Domain" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^old-domain\.com$" />
</conditions>
<action type="Redirect" url="https://new-domain.com/{R:1}"
redirectType="Permanent" />
</rule>
<!-- 强制小写 URL -->
<rule name="Lowercase URL" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" url="{ToLower:{URL}}" />
</rule>
</rules>
<!-- 出站规则:修改响应内容中的链接 -->
<outboundRules>
<rule name="Add Strict-Transport-Security">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Rewrite" value="max-age=31536000; includeSubDomains" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>ARR 反向代理
Application Request Routing(ARR)使 IIS 具备反向代理能力,可用于负载均衡多个后端服务器。
安装 ARR 模块
# 通过 Web Platform Installer 或下载安装包安装 ARR 3.0
# 启用代理功能
Set-WebConfigurationProperty -Filter "system.webServer/proxy" -Name enabled -Value True配置反向代理
<!-- web.config -->
<configuration>
<system.webServer>
<proxy enabled="true" />
<rewrite>
<rules>
<rule name="Reverse Proxy" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^https?://" />
</conditions>
<!-- 转发到后端 Java 应用 -->
<action type="Rewrite" url="http://localhost:8080/{R:1}" />
</rule>
</rules>
<!-- 服务器变量透传真实 IP -->
<allowedServerVariables>
<add name="REMOTE_ADDR" />
<add name="HTTP_X_FORWARDED_FOR" />
<add name="HTTP_X_FORWARDED_PROTO" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</configuration>负载均衡配置
ARR 可以通过服务器场实现负载均衡:
# 创建服务器场
New-WebFarm -Name "BackendFarm" -Servers @("192.168.1.10:8080", "192.168.1.11:8080")
# 设置负载均衡算法(LeastRequests / WeightedRoundRobin / etc.)
Set-WebConfigurationProperty -Filter "system.webServer/webFarms/farm[@name='BackendFarm']/applicationRequestRouting" `
-Name "loadBalance" -Value "LeastRequests"
# 健康检查
Set-WebConfigurationProperty -Filter "system.webServer/webFarms/farm[@name='BackendFarm']/applicationRequestRouting/healthCheck" `
-Name "url" -Value "/actuator/health"
Set-WebConfigurationProperty -Filter "system.webServer/webFarms/farm[@name='BackendFarm']/applicationRequestRouting/healthCheck" `
-Name "interval" -Value "00:00:30"Web.config 完整示例
综合配置示例:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.8" />
<httpRuntime targetFramework="4.8"
maxRequestLength="102400"
executionTimeout="300" />
<customErrors mode="RemoteOnly" />
</system.web>
<system.webServer>
<!-- 静态资源缓存 -->
<staticContent>
<clientCache cacheControlMode="UseMaxAge"
cacheControlMaxAge="7.00:00:00" />
<mimeMap fileExtension=".woff2" mimeType="font/woff2" />
</staticContent>
<!-- 安全头部 -->
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="DENY" />
<add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
</customHeaders>
</httpProtocol>
<!-- 压缩 -->
<urlCompression doStaticCompression="true"
doDynamicCompression="true"
dynamicCompressionBeforeCache="true" />
<!-- 默认文档 -->
<defaultDocument>
<files>
<clear />
<add value="index.html" />
<add value="index.htm" />
<add value="default.aspx" />
</files>
</defaultDocument>
<!-- 目录浏览 -->
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>对比选型表
| 维度 | Tomcat | Undertow | Caddy | Nginx | IIS |
|---|---|---|---|---|---|
| 类型 | Java Servlet 容器 | Java Web 服务器 | HTTP 服务器 + 反向代理 | HTTP 服务器 + 反向代理 | Windows Web 服务器 |
| 主要用途 | 部署 WAR 应用 | Spring Boot 内嵌容器 | 自动 HTTPS 反向代理 | 高性能反向代理 / 静态文件 | Windows 系 .NET / ASP 应用 |
| Java 生态 | 原生支持 | 深度集成 | 不支持(但可反代 Java) | 不支持(但可反代 Java) | 有限(可通过 JNBridge) |
| 配置复杂度 | 中等(XML) | 低(YAML) | 低(Caddyfile) | 中等偏高(nginx.conf) | 中等(GUI + XML) |
| 自动 HTTPS | 不支持 | 不支持 | 原生支持(Let's Encrypt) | 需 Let's Encrypt + certbot | 需购买或手动导入证书 |
| 静态文件性能 | 一般 | 良好 | 优秀 | 优秀 | 优秀 |
| 并发模型 | 线程池(BIO/NIO) | NIO2(XNIO) | Go goroutine | 事件驱动(epoll) | 内核级 I/O 完成端口 |
| 内存占用 | 较高(JVM) | 中等(JVM) | 低(Go 二进制) | 低 | 中等 |
| 安装方式 | 下载 tar/zip 解压 | Maven 依赖 | 单二进制文件 | 编译或包管理 | Windows Features |
| 集群/Session | DeltaManager / Redis | Spring Session 集成 | 无内置(需外部) | upstream 模块 | ARR + 状态服务 |
| 插件/扩展 | Valve、Realm | Handler、ExchangeHandler | Caddyfile 指令模块 | 丰富的第三方模块 | ISAPI、HttpModule |
| 适用团队 | Java 团队 | Java 团队(Spring Boot) | DevOps / SRE | 运维 / SRE | Windows 运维团队 |
| 典型场景 | 传统 Java 单体应用 | 微服务 Spring Boot 项目 | API 网关、小团队项目 | 高并发网关、静态 CDN | 企业内部系统、.NET 应用 |
选型建议
- Java 服务直连生产:优先使用 Spring Boot + Undertow 内嵌容器,减少运维组件。
- 需要 WAR 部署:选择 Tomcat,支持 Servlet 全特性、JMX 监控、集群管理。
- 反向代理 + 自动 HTTPS:中小型项目首选 Caddy,大型项目或复杂路由选择 Nginx。
- Windows 环境:IIS 与 AD / .NET 生态深度整合,是 Windows 平台的事实标准。
- 混合架构:前端 Nginx / Caddy 做反向代理 + TLS 终止,后端 Java 应用使用 Undertow / Tomcat。