系列导读:本系列将带你从零开始,系统掌握 Nginx 与 Tomcat 整合的核心技能。第一篇聚焦基础环境搭建,为后续深入学习打下坚实基础。
文章目录
-
- [前言:为什么需要 Nginx + Tomcat?](#前言:为什么需要 Nginx + Tomcat?)
- 一、架构原理:动静分离的核心思想
-
- [1.1 传统架构 vs 整合架构](#1.1 传统架构 vs 整合架构)
- [1.2 请求处理流程](#1.2 请求处理流程)
- [1.3 核心组件职责](#1.3 核心组件职责)
- 二、环境准备与安装
-
- [2.1 系统环境要求](#2.1 系统环境要求)
- [2.2 JDK 安装](#2.2 JDK 安装)
- [2.3 Tomcat 安装](#2.3 Tomcat 安装)
- [2.4 Nginx 安装](#2.4 Nginx 安装)
- [2.5 创建系统服务(Tomcat)](#2.5 创建系统服务(Tomcat))
- [三、Tomcat 基础配置](#三、Tomcat 基础配置)
-
- [3.1 目录结构说明](#3.1 目录结构说明)
- [3.2 server.xml 核心配置](#3.2 server.xml 核心配置)
- [3.3 Connector 参数详解](#3.3 Connector 参数详解)
- [3.4 JVM 内存配置](#3.4 JVM 内存配置)
- [3.5 部署测试应用](#3.5 部署测试应用)
- [四、Nginx 反向代理配置](#四、Nginx 反向代理配置)
-
- [4.1 基础反向代理配置](#4.1 基础反向代理配置)
- [4.2 动静分离配置](#4.2 动静分离配置)
- [4.3 验证配置并重载](#4.3 验证配置并重载)
- 五、整合验证与测试
-
- [5.1 功能测试](#5.1 功能测试)
- [5.2 性能测试](#5.2 性能测试)
- [5.3 日志验证](#5.3 日志验证)
- 六、常见问题与解决方案
-
- [6.1 502 Bad Gateway](#6.1 502 Bad Gateway)
- [6.2 静态资源 404](#6.2 静态资源 404)
- [6.3 请求头丢失](#6.3 请求头丢失)
- [6.4 中文乱码](#6.4 中文乱码)
- 总结
前言:为什么需要 Nginx + Tomcat?
在 Java Web 应用部署中,Tomcat 是最常用的 Servlet 容器,但它在处理静态资源和高并发方面存在局限性。Nginx + Tomcat 的组合完美解决了这些问题:
┌─────────────────────────────────────────────────────────────┐
│ Nginx + Tomcat 架构优势 │
├─────────────────────────────────────────────────────────────┤
│ 🚀 静态资源处理 → Nginx 处理静态文件,性能提升 10 倍+ │
│ ⚖️ 负载均衡 → 多 Tomcat 实例,流量分发,高可用 │
│ 🔒 安全防护 → Nginx 作为前置,隐藏后端架构 │
│ 💾 缓存优化 → Nginx 缓存热点数据,减轻 Tomcat 压力 │
│ 🔌 SSL 终端 → Nginx 处理 HTTPS,Tomcat 专注业务 │
└─────────────────────────────────────────────────────────────┘
核心价值对比:
| 能力 | 单独 Tomcat | Nginx + Tomcat |
|---|---|---|
| 静态资源 | 较慢,占用线程 | 极快,零拷贝 |
| 并发连接 | 数百级别 | 数万级别 |
| 负载均衡 | 不支持 | 原生支持 |
| SSL 性能 | CPU 消耗大 | 优化后极快 |
| 故障隔离 | 单点故障 | 多实例容错 |
一、架构原理:动静分离的核心思想
1.1 传统架构 vs 整合架构
传统架构(单独 Tomcat):
客户端 → Tomcat (8080)
├── 处理静态资源 (CSS/JS/图片)
└── 处理动态请求 (JSP/Servlet)
问题:
- ❌ 静态资源占用 Tomcat 线程
- ❌ 并发能力受限
- ❌ 无法水平扩展
整合架构(Nginx + Tomcat):
┌→ Tomcat1 (8080) → 动态请求
客户端 → Nginx (80) ─┼→ Tomcat2 (8081) → 动态请求
└→ 本地文件系统 → 静态资源
优势:
- ✅ Nginx 处理静态资源,性能极高
- ✅ Tomcat 专注动态请求,资源利用率高
- ✅ 支持负载均衡,水平扩展
1.2 请求处理流程
HTTP 请求到达 Nginx
↓
判断请求类型
↓
┌───────┴───────┐
↓ ↓
静态资源 动态请求
(.css/.js/.jpg) (.jsp/.do/.action)
↓ ↓
Nginx 直接返回 proxy_pass 转发
↓
Tomcat 处理
↓
返回响应
1.3 核心组件职责
| 组件 | 职责 | 端口 |
|---|---|---|
| Nginx | 反向代理、静态资源、负载均衡、SSL | 80/443 |
| Tomcat | Java Web 容器、Servlet 处理 | 8080 |
二、环境准备与安装
2.1 系统环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| 操作系统 | CentOS 7+ / Ubuntu 18+ | Linux 系统最佳 |
| JDK | 8+ / 11 LTS | Tomcat 运行依赖 |
| Nginx | 1.18+ | 稳定版 |
| Tomcat | 9.0+ | 最新稳定版 |
2.2 JDK 安装
bash
# ==================== CentOS/RHEL ====================
# 安装 OpenJDK 11
sudo yum install -y java-11-openjdk java-11-openjdk-devel
# 验证安装
java -version
# 输出:openjdk version "11.0.x"
# 配置 JAVA_HOME
sudo tee /etc/profile.d/java.sh << 'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /etc/profile.d/java.sh
# ==================== Ubuntu/Debian ====================
sudo apt update
sudo apt install -y openjdk-11-jdk
java -version
2.3 Tomcat 安装
bash
# 创建应用目录
sudo mkdir -p /opt/tomcat
cd /opt/tomcat
# 下载 Tomcat 9(最新稳定版)
TOMCAT_VERSION="9.0.85"
wget https://downloads.apache.org/tomcat/tomcat-9/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz
# 解压
tar -xzf apache-tomcat-${TOMCAT_VERSION}.tar.gz
mv apache-tomcat-${TOMCAT_VERSION} tomcat9
# 创建软链接(方便后续升级)
ln -s /opt/tomcat/tomcat9 /opt/tomcat/current
# 设置权限
sudo chown -R root:root /opt/tomcat
chmod +x /opt/tomcat/current/bin/*.sh
# 配置环境变量
sudo tee /etc/profile.d/tomcat.sh << 'EOF'
export CATALINA_HOME=/opt/tomcat/current
export PATH=$CATALINA_HOME/bin:$PATH
EOF
source /etc/profile.d/tomcat.sh
2.4 Nginx 安装
bash
# ==================== CentOS/RHEL ====================
sudo yum install -y epel-release
sudo yum install -y nginx
# ==================== Ubuntu/Debian ====================
sudo apt update
sudo apt install -y nginx
# ==================== 验证安装 ====================
nginx -v
# 输出:nginx version: nginx/1.20.1
# 启动 Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
2.5 创建系统服务(Tomcat)
bash
# 创建 Tomcat systemd 服务
sudo tee /etc/systemd/system/tomcat.service << 'EOF'
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk
Environment=CATALINA_PID=/opt/tomcat/current/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat/current
Environment=CATALINA_BASE=/opt/tomcat/current
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'
ExecStart=/opt/tomcat/current/bin/startup.sh
ExecStop=/opt/tomcat/current/bin/shutdown.sh
User=root
Group=root
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 重载 systemd
sudo systemctl daemon-reload
# 启动 Tomcat
sudo systemctl start tomcat
sudo systemctl enable tomcat
# 验证
sudo systemctl status tomcat
三、Tomcat 基础配置
3.1 目录结构说明
/opt/tomcat/current/
├── bin/ # 启动脚本
│ ├── startup.sh # 启动
│ ├── shutdown.sh # 停止
│ └── catalina.sh # 核心脚本
├── conf/ # 配置文件
│ ├── server.xml # 主配置文件
│ ├── web.xml # Web 应用默认配置
│ └── context.xml # 上下文配置
├── lib/ # Tomcat 类库
├── logs/ # 日志目录
│ ├── catalina.out # 控制台日志
│ └── localhost_access_log.*.txt # 访问日志
├── temp/ # 临时文件
├── webapps/ # Web 应用部署目录
│ ├── ROOT/ # 默认应用
│ └── your-app/ # 你的应用
└── work/ # JSP 编译目录
3.2 server.xml 核心配置
xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Service name="Catalina">
<!-- HTTP 连接器 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200"
minSpareThreads="25"
acceptCount="100"
URIEncoding="UTF-8"
enableLookups="false"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/css,application/json,application/javascript" />
<!-- AJP 连接器(可选,用于与 Nginx 通信)-->
<Connector port="8009" protocol="AJP/1.3"
redirectPort="8443"
secretRequired="false" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 访问日志配置 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
3.3 Connector 参数详解
| 参数 | 说明 | 推荐值 |
|---|---|---|
port |
监听端口 | 8080 |
maxThreads |
最大线程数 | 200-500 |
minSpareThreads |
最小空闲线程 | 25 |
acceptCount |
等待队列长度 | 100 |
connectionTimeout |
连接超时 | 20000ms |
enableLookups |
DNS 反查 | false(关闭) |
compression |
Gzip 压缩 | on |
URIEncoding |
URI 编码 | UTF-8 |
3.4 JVM 内存配置
bash
# 编辑 setenv.sh(推荐方式)
sudo tee /opt/tomcat/current/bin/setenv.sh << 'EOF'
#!/bin/bash
# JVM 内存配置
export JAVA_OPTS="-Xms512m -Xmx1024m"
# GC 配置
export JAVA_OPTS="$JAVA_OPTS -XX:+UseParallelGC -XX:ParallelGCThreads=4"
# 元空间配置(JDK 8+)
export JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
# 远程调试(开发环境)
# export JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
# JMX 监控(可选)
export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
EOF
chmod +x /opt/tomcat/current/bin/setenv.sh
3.5 部署测试应用
bash
# 创建测试应用目录
mkdir -p /opt/tomcat/current/webapps/test
# 创建测试 JSP 页面
cat > /opt/tomcat/current/webapps/test/index.jsp << 'EOF'
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Tomcat Test Page</title>
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
.container {
background: white;
padding: 40px;
border-radius: 20px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
text-align: center;
}
h1 { color: #333; }
.info { color: #666; margin: 10px 0; }
.highlight { color: #667eea; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>🎉 Tomcat Running!</h1>
<p class="info">Server: <span class="highlight"><%= request.getServerName() %></span></p>
<p class="info">Port: <span class="highlight"><%= request.getServerPort() %></span></p>
<p class="info">Time: <span class="highlight"><%= new java.util.Date() %></span></p>
<p class="info">Session ID: <span class="highlight"><%= session.getId() %></span></p>
</div>
</body>
</html>
EOF
# 重启 Tomcat
sudo systemctl restart tomcat
# 测试访问
curl http://localhost:8080/test/
四、Nginx 反向代理配置
4.1 基础反向代理配置
nginx
# /etc/nginx/conf.d/tomcat-proxy.conf
upstream tomcat_backend {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80;
server_name your-domain.com;
# 访问日志
access_log /var/log/nginx/tomcat.access.log;
error_log /var/log/nginx/tomcat.error.log;
# 动态请求转发到 Tomcat
location / {
proxy_pass http://tomcat_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_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲配置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
}
}
4.2 动静分离配置
nginx
# /etc/nginx/conf.d/tomcat-proxy.conf
upstream tomcat_backend {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80;
server_name your-domain.com;
root /opt/tomcat/current/webapps;
# ==================== 静态资源(Nginx 直接处理)====================
# CSS 文件
location ~* \.css$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# JavaScript 文件
location ~* \.js$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}
# 图片文件
location ~* \.(jpg|jpeg|png|gif|ico|webp|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 字体文件
location ~* \.(woff|woff2|ttf|otf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# ==================== 动态请求(转发到 Tomcat)====================
# JSP 文件
location ~* \.jsp$ {
proxy_pass http://tomcat_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;
}
# Servlet 路径
location ~* ^/(servlet|action|do|api)/ {
proxy_pass http://tomcat_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 默认转发
location / {
# 先尝试本地静态文件,不存在则转发 Tomcat
try_files $uri @tomcat;
}
location @tomcat {
proxy_pass http://tomcat_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;
}
}
4.3 验证配置并重载
bash
# 检查 Nginx 配置语法
sudo nginx -t
# 重载配置
sudo nginx -s reload
# 或
sudo systemctl reload nginx
# 测试访问
curl -I http://localhost/test/
五、整合验证与测试
5.1 功能测试
bash
# 测试静态资源(Nginx 处理)
curl -I http://localhost/test/style.css
# 测试动态请求(Tomcat 处理)
curl http://localhost/test/index.jsp
# 查看响应头,确认经过 Nginx
curl -I http://localhost/test/
# 应看到:Server: nginx
5.2 性能测试
bash
# 安装 ab 测试工具
sudo yum install -y httpd-tools # CentOS
# 或
sudo apt install -y apache2-utils # Ubuntu
# 测试静态资源(Nginx)
ab -n 10000 -c 100 http://localhost/test/style.css
# 测试动态请求(Tomcat)
ab -n 1000 -c 50 http://localhost/test/index.jsp
5.3 日志验证
bash
# 查看 Nginx 访问日志
tail -f /var/log/nginx/tomcat.access.log
# 查看 Tomcat 日志
tail -f /opt/tomcat/current/logs/catalina.out
# 查看 Tomcat 访问日志
tail -f /opt/tomcat/current/logs/localhost_access_log.*.txt
六、常见问题与解决方案
6.1 502 Bad Gateway
原因:Tomcat 未启动或端口错误
bash
# 检查 Tomcat 状态
sudo systemctl status tomcat
# 检查端口监听
netstat -tlnp | grep 8080
# 检查 SELinux(CentOS)
sudo setenforce 0 # 临时关闭
# 或配置 SELinux 策略
sudo setsebool -P httpd_can_network_connect 1
6.2 静态资源 404
原因:Nginx root 路径配置错误
nginx
# 确保 root 指向正确的 webapps 目录
server {
root /opt/tomcat/current/webapps; # 注意路径
# ...
}
6.3 请求头丢失
原因:未正确传递请求头
nginx
# 确保配置了 proxy_set_header
location / {
proxy_pass http://tomcat_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;
}
6.4 中文乱码
解决方案:
xml
<!-- Tomcat server.xml -->
<Connector port="8080" URIEncoding="UTF-8" ... />
nginx
# Nginx 配置
server {
charset utf-8;
# ...
}
总结
本文作为 Nginx + Tomcat 整合系列的开篇,我们完成了:
✅ 理解整合架构 :动静分离、反向代理的核心思想
✅ 环境搭建 :JDK、Tomcat、Nginx 的安装配置
✅ Tomcat 配置 :server.xml、JVM 内存、部署应用
✅ Nginx 配置 :反向代理、动静分离
✅ 整合验证:功能测试、性能测试、日志查看
架构总结图:
┌─────────────────────────────────────────────────────────┐
│ 客户端请求 │
└─────────────────────────┬───────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Nginx (80/443) │
│ ┌─────────────────┐ ┌─────────────────────────────┐ │
│ │ 静态资源处理 │ │ 动态请求转发 │ │
│ │ (.css/.js/.jpg)│ │ proxy_pass → Tomcat │ │
│ └─────────────────┘ └─────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Tomcat (8080) │
│ ┌─────────────────────────────────────────────────────┐│
│ │ Servlet 容器 / JSP 处理 / 业务逻辑 ││
│ └─────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────┘
下一篇预告 :(Nginx + Tomcat 整合实战(二):反向代理深度配置),将深入讲解 proxy_pass 高级配置、请求头处理、WebSocket 代理等核心技能。
作者 :刘~浪地球
系列 :Nginx + Tomcat 整合实战(一)
更新时间:2026-03-30