在 Java 后端服务部署中,Nginx 和 Tomcat 的典型配合模式是:Nginx 作为反向X_X(Reverse Proxy)和 Web 服务器前置,Tomcat 作为应用服务器专注运行 Java Servlet(如 Spring Boot 应用)。这种组合充分发挥各自优势,是生产环境的主流实践。
以下是详细配合方式、原理及最佳实践:
✅ 一、角色分工(核心原则)
| 组件 | 角色与职责 | 为什么不用它单独干? |
|---|---|---|
| Nginx | ✅ 静态资源服务(JS/CSS/图片) ✅ HTTPS 终止(SSL/TLS 卸载) ✅ 反向X_X + 负载均衡(多 Tomcat 实例) ✅ 请求限流、缓存、压缩、访问日志、WAF 基础防护 ✅ 高并发连接处理(异步非阻塞 I/O) |
不支持 Java Servlet/JSP,无法运行业务逻辑 |
| Tomcat | ✅ 运行 Java Web 应用(Servlet/Filter/Listener) ✅ 管理 Spring Boot 内嵌容器(或独立部署) ✅ 处理业务逻辑、数据库交互、事务等 |
默认 HTTP 端口(8080)不安全;静态资源性能差;无原生 HTTPS/负载均衡能力 |
💡 关键点:用户 → Nginx(80/443)→ Tomcat(8080/8009),Tomcat 不直接暴露公网端口。
✅ 二、典型部署架构(单机 & 集群)
▪ 场景1:单应用(Spring Boot 内嵌 Tomcat)
用户浏览器
↓ (HTTPS:443)
Nginx(反向X_X + SSL 终止)
↓ (HTTP:8080,内网通信)
Spring Boot(内置 Tomcat,默认端口 8080)
- ✅ Nginx 配置示例(
/etc/nginx/conf.d/app.conf):upstream backend { server 127.0.0.1:8080; # 或 docker 容器名:8080 }
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
# 静态资源优先由 Nginx 服务(提升性能)
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
add_header Cache-Control "public, immutable";
root /opt/myapp/static/;
}
# 动态请求X_X到 Tomcat
location / {
proxy_pass http://backend;
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 超时设置(避免长连接阻塞)
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 60s;
proxy_buffering on;
}
}
#### ▪ 场景2:多实例集群(负载均衡)
```mermaid
graph LR
A[用户] --> B[Nginx]
B --> C[Tomcat-1:8080]
B --> D[Tomcat-2:8080]
B --> E[Tomcat-3:8080]
upstream支持轮询、权重、IP Hash、least_conn 等策略:upstream backend { ip_hash; # 保证同一用户请求落到同一 Tomcat(需 session 共享或无状态设计) server 192.168.1.10:8080 weight=3; server 192.168.1.11:8080 weight=2; server 192.168.1.12:8080 backup; # 故障转移 }
⚠️ 注意:若使用
ip_hash,务必确保 Tomcat Session 可共享(如 Redis 存储)或应用设计为完全无状态(推荐!)。
✅ 三、高级协作场景
| 场景 | 如何配合 |
|---|---|
| HTTPS 卸载 | Nginx 解密 HTTPS → 以 HTTP 明文转发给 Tomcat(省去 Tomcat SSL 配置与 CPU 开销) |
| 动静分离 | Nginx 直接返回 /static/, /images/ 等路径资源;其余 /api/** X_X至 Tomcat |
| API 网关基础功能 | Nginx 实现限流(limit_req)、黑白名单、URL 重写(rewrite)、跨域头(add_header Access-Control-Allow-Origin *) |
| 健康检查 | Nginx health_check 模块(商业版)或自定义 location /health { proxy_pass http://backend/health; } |
| A/B 测试 / 灰度发布 | 根据请求头/参数/cookie 将流量分发到不同 upstream(map + split_clients) |
✅ 四、Tomcat 侧重要配置(配合 Nginx)
-
禁用 Tomcat HTTP Connector(仅保留 AJP 或仅内部 HTTP)
若 Nginx 是唯一入口,关闭 Tomcat 的server.xml中默认<Connector port="8080">的address="127.0.0.1"限制(或防火墙屏蔽 8080 公网访问)。 -
启用
RemoteIpFilter(关键!)
因真实 IP 被 Nginx X_X隐藏,需让 Spring Boot/Tomcat 识别X-Forwarded-For:// Spring Boot 2.6+ 自动配置(application.yml) server: forward-headers-strategy: framework # 或 native(Tomcat 原生支持)或手动注册 Filter(兼容老版本)。
-
Session 配置(若需会话)
- ✅ 推荐:无状态化(JWT Token + Redis 缓存用户信息)
- ❌ 避免:Tomcat Session 复制(性能差)
- ✅ 可选:Spring Session + Redis(统一管理 session)
✅ 五、为什么不直接用 Tomcat 对外提供服务?
| 问题 | Nginx 解决方案 |
|---|---|
| 静态资源慢 | Nginx 静态文件性能是 Tomcat 的 5–10 倍 |
| HTTPS 性能开销大 | Nginx 优化的 SSL 引擎(OpenSSL/BoringSSL)更高效 |
| 无法灵活路由/限流/缓存 | Nginx 提供成熟模块(ngx_http_limit_req_module 等) |
| 单点故障/扩展性差 | Nginx 可前置多台 Tomcat,平滑扩容 |
| 日志格式/访问控制粒度粗 | Nginx 日志可按 path/status/user-agent 精细统计 |
📌 补充:Spring Boot 项目可选择 内嵌 Tomcat(默认) 或 外置 Tomcat 部署(war 包),Nginx 都可统一X_X,后者更适合传统 Java EE 环境。
✅ 六、运维建议(生产 checklist)
- ✅ Nginx 开启
gzip on+gzip_types压缩文本响应 - ✅ 设置
client_max_body_size 10M(防大文件上传失败) - ✅ Tomcat
maxThreads=200(根据 CPU 核数调整,避免线程过多 GC) - ✅ Nginx 与 Tomcat 时间同步(
ntpdate),避免 token 签名时间校验失败 - ✅ 使用
systemd管理 Nginx/Tomcat,配置Restart=always - ✅ 日志分离:Nginx 访问日志 + Tomcat
catalina.out+ 应用日志(Logback) - ✅ 监控:Nginx stub_status / Tomcat JMX / Prometheus + Grafana
如有具体场景(如 Docker/K8s 部署、Spring Cloud Gateway 替代 Nginx、WebSocket 支持),我可进一步给出针对性方案。欢迎继续提问! 😊
云计算HECS