Nginx + Tomcat 整合实战(一):基础环境搭建与整合入门

系列导读:本系列将带你从零开始,系统掌握 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 &quot;%r&quot; %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

相关推荐
刘~浪地球2 小时前
Nginx + Tomcat 整合实战(四):会话管理与共享详解
运维·nginx·tomcat
曹牧2 小时前
Tomcat连接池异常排查
java·tomcat
为爱停留2 小时前
HTTPS 域名访问与 Nginx 全链路说明
网络协议·nginx·https
zs宝来了3 小时前
Spring Boot 内嵌 Tomcat 原理:Tomcat ServletWebServerFactory 源码解析
spring boot·tomcat·内嵌容器·webserverfactory
he___H3 小时前
Nginx+lua+openresty
nginx·lua·openresty
曹牧3 小时前
Tomcat中间件能够提供的能力
java·中间件·tomcat
fengtangjiang3 小时前
tomcat和国产web中间件区别和联系
前端·中间件·tomcat
刘~浪地球4 小时前
Nginx + Tomcat 整合实战(三):负载均衡与集群部署
nginx·tomcat·负载均衡
灰阳阳14 小时前
Dockerfile实践-构建Nginx镜像
运维·nginx·docker·dockerfile