在 Java 后端服务部署中,Nginx 与 Tomcat 的典型配合模式是:Nginx 作为反向X_X(Reverse Proxy)和 Web 服务器前置层,Tomcat 作为应用服务器(Servlet 容器)专注运行 Java Web 应用(如 Spring Boot、传统 WAR 包)。这种组合充分发挥各自优势,是生产环境的主流架构。
以下是核心配合方式与最佳实践详解:
✅ 一、角色分工(Why 配合?)
| 组件 | 主要职责 | 优势 |
|---|---|---|
| Nginx | – 静态资源(JS/CSS/图片/HTML)直接服务 – 反向X_X HTTP/HTTPS 请求到 Tomcat – 负载均衡(多 Tomcat 实例) – SSL/TLS 终止(HTTPS 卸载) – 请求限流、缓存、日志、防攻击(如 CC) |
高并发、低内存占用、高性能静态服务、成熟稳定、配置灵活 |
| Tomcat | – 解析 Servlet/JSP,执行 Java 业务逻辑 – 管理 Session、连接池、JNDI 等 Java EE 特性 – 处理动态请求(如 /api/**, /user/login) |
原生支持 Java Web 标准(Servlet/JSP)、Spring 生态友好、热部署(开发期) |
💡 关键原则:Nginx 不处理 Java 逻辑,只做“流量调度 + 静态服务”;Tomcat 专注“业务执行”,不暴露在公网。
✅ 二、典型部署拓扑
graph LR
A[客户端] --> B[Nginx]
B --> C[静态资源 /static/*]
B --> D[动态请求 /api/** → Tomcat]
B --> E[负载均衡:Tomcat1, Tomcat2, ...]
D --> F[Tomcat 单实例]
E --> F
✅ 三、Nginx 核心配置示例(nginx.conf 或 sites-available/myapp)
upstream backend_tomcat {
# 负载均衡策略(默认轮询)
server 127.0.0.1:8080 weight=3;
server 127.0.0.1:8081 weight=1; # 可扩展多个 Tomcat
# keepalive 32; # 启用长连接,提升性能
}
server {
listen 80;
server_name myapp.example.com;
# ✅ HTTPS 重定向(推荐强制 HTTPS)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.example.com;
# SSL 配置(证书路径按实际调整)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# ✅ 静态资源:Nginx 直接服务,不转发给 Tomcat
location ~ ^/(static|images|css|js|fonts)/ {
root /var/www/myapp; # 或 alias /var/www/myapp/static;
expires 1y;
add_header Cache-Control "public, immutable";
}
# ✅ 动态请求:反向X_X到 Tomcat
location / {
proxy_pass http://backend_tomcat/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# ✅ 关键:传递真实协议和端口,避免 Spring Security/Redirect 问题
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Proto https;
# ✅ 超时设置(防止 Tomcat 慢响应拖垮 Nginx)
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# ✅ WebSocket 支持(若应用用到)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# ✅ 可选:健康检查接口(供运维监控)
location /health {
return 200 "OKn";
add_header Content-Type text/plain;
}
}
✅ 四、Tomcat 关键适配配置
-
关闭 Tomcat 自带 HTTP 端口(可选但推荐)
若仅通过 Nginx 访问,可在conf/server.xml中注释或禁用Connector port="8080",仅保留 AJP(如需)或保留但限制内网访问:<!-- 仅允许本地 Nginx 访问 --> <Connector port="8080" protocol="HTTP/1.1" address="127.0.0.1" connectionTimeout="20000" redirectPort="8443" /> -
正确识别客户端真实 IP(配合 Nginx 的
X-Forwarded-For)
在conf/server.xml的<Valve>中启用 Remote IP 过滤器:<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https" />✅ 此后
request.getRemoteAddr()将返回真实客户端 IP,而非127.0.0.1 -
Spring Boot 应用额外配置(
application.yml)server: forward-headers-strategy: framework # 启用对 X-Forwarded-* 的自动解析 # 或显式配置(旧版) # server.tomcat.remote-ip-header: x-forwarded-for # server.tomcat.protocol-header: x-forwarded-proto
✅ 五、进阶场景与优化
| 场景 | 方案 |
|---|---|
| 高可用 & 扩容 | Nginx + 多台 Tomcat(横向扩展),配合 Consul/Eureka 做服务发现(需动态 upstream) |
| 动静分离 | 静态资源托管至 CDN(如阿里云 OSS + CDN),Nginx 仅X_X动态请求 |
| 灰度发布 | Nginx 根据 Cookie/Header 路由到不同 Tomcat 分组(split_clients 或 map 指令) |
| API 网关替代 | 复杂场景可升级为 Spring Cloud Gateway / Kong / APISIX,Nginx 退为边缘负载均衡器 |
| 安全加固 | Nginx 层添加 mod_security、WAF 规则、防盗链、Referer 白名单等 |
⚠️ 常见陷阱与避坑指南
- ❌ 不要让 Tomcat 直接监听 80/443 端口 → 易受攻击、无静态提速、SSL 配置复杂
- ❌ *忽略 `X-Forwarded-
头导致 Spring Security 重定向跳 HTTP 或 IP 错误** → 务必配置RemoteIpValve+ Spring 的forward-headers-strategy` - ❌ Nginx 未设置超时,Tomcat 长任务导致连接堆积 → 必设
proxy_read_timeout(建议 ≥ Tomcat 的connectionTimeout) - ❌ 静态资源路径配置错误(
rootvsalias) → 注意末尾/和路径拼接逻辑 - ❌ WebSocket 未开启 HTTP/1.1 升级头 → 导致连接失败(见上方
Upgrade配置)
✅ 总结:一句话最佳实践
用 Nginx 做“门卫 + 快递员”(管入口、分发、静态服务、安全防护),用 Tomcat 做“程序员”(专注写好 Java 业务逻辑),两者通过标准化 HTTP 协议协作,各司其职,稳定高效。
如需我提供:
🔹 完整的 nginx.conf + server.xml 示例
🔹 Docker Compose 一键部署脚本
🔹 Spring Boot + Nginx + HTTPS 自动化配置模板
欢迎随时告诉我 👍
CDNK博客