Nginx + Tomcat 实战:反向代理、负载均衡与动静分离

Nginx实战:反向代理、负载均衡与Tomcat集成部署

前言

在Web应用架构中,Nginx凭借高并发处理能力、灵活的请求转发机制,成为连接用户与后端Tomcat的核心枢纽。我们可以用一个生动的比喻理解这套架构:

把完整的网站服务想象成一家餐厅

  • 顾客 = 网站的用户/访问者
  • 餐厅招牌和迎宾(Nginx) = 负责在门口接待顾客,引导他们去座位或者直接提供快餐
  • 厨房(Tomcat) = 负责制作复杂的、需要现做的"大菜"(动态内容)
  • 快餐窗口(Nginx 本身) = 迎宾员也可以直接从窗口拿出准备好的"汉堡/薯条"(静态文件)

本文聚焦Nginx核心实战场景,围绕"反向代理(请求转发)、负载均衡(压力分流)、Tomcat后端适配"三大核心,结合明确的"通俗解释+技术解释"、博客实战细节与可落地配置,提供全面且精简的方案,助力快速搭建稳定的动态服务架构。

一、反向代理:Nginx转发请求到Tomcat

1.1 反向代理原理

通俗解释

反向代理就像一个公司的前台/总机 。客户打电话来,只知道总机的号码(域名),总机接到电话后,根据客户的需求,悄悄地把电话转接到内部相应的部门(比如销售部、技术部,也就是后端的Tomcat服务器)。客户并不知道,也无需知道具体是哪个部门接的电话,全程只和总机沟通。

技术解释
  • 正向代理 :代表客户端发起请求,替客户端访问外部资源(如科学上网工具),目标服务器无法获取客户端真实IP。
  • 反向代理 :代表服务器端接收请求,替后端服务器转发请求,客户端无法获取后端服务器真实IP,仅与反向代理服务器交互。
  • Nginx支持两种核心请求匹配方式:① URI前缀匹配(如location /),适合全局请求转发;② 正则匹配(如location ~*\.jsp$),适合按文件后缀精准转发动态请求。
  • 核心流程:客户端 → Nginx(反向代理) → 后端Tomcat → Nginx → 客户端。

1.2 反向代理核心价值

通俗解释
  • 保护后端"办公室":客户只知道总机号码,不会直接找到具体部门,避免无关人员打扰(黑客攻击)。
  • 统一"接待标准":所有客户请求都先经过前台,方便统一登记(日志记录)、核实身份(权限校验)、分流引导(流量控制)。
  • 灵活"对接需求":前台能根据客户要办的业务(请求类型),精准转到对应部门,不用客户自己找。
技术解释
  • 隐藏后端服务器IP,降低直接暴露在公网的攻击风险,提升服务安全性。
  • 统一请求入口,便于集中配置权限校验、日志收集、流量限制等功能,简化架构管理。
  • 为负载均衡、动静分离提供基础,支持按路径或后缀精准转发请求,适配多样化业务场景。
  • 隔离后端架构变更,客户端无需感知后端服务器增减或地址变更,提升架构灵活性。

1.3 反向代理基础配置(对接单台Tomcat)

假设后端Tomcat部署在192.168.10.10:8080,通过Nginx代理对外提供访问,配置如下:

  1. 编辑Nginx主配置文件:
bash 复制代码
vim /usr/local/nginx/conf/nginx.conf
  1. 添加代理配置(包含完整请求头传递):
nginx 复制代码
# 定义上游的Tomcat服务器
upstream tomcat_server {
    server 192.168.10.10:8080; # 单台Tomcat节点
}

server {
    listen 80;                  # Nginx监听HTTP默认端口80
    server_name www.mywebsite.com; # 对外访问域名
    charset utf-8; # 统一字符编码,避免中文乱码

    location / {
        proxy_pass http://tomcat_server; # 将所有请求转发给Tomcat服务器组
        proxy_set_header Host $host; # 保留用户访问的原始域名
        proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录请求转发路径
    }

    # 正则匹配动态请求,精准转发(可选)
    location ~*\.jsp$ {
        proxy_pass http://tomcat_server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
  1. 验证配置并生效:
bash 复制代码
nginx -t  # 检查配置语法
nginx -s reload  # 重载配置,无需停机
# 或使用系统服务重载
systemctl reload nginx

1.4 动静分离:Nginx高效处理静态资源

通俗解释

就像餐厅分工:顾客点汉堡、可乐(静态资源,如图片、CSS),迎宾员直接从快餐窗口拿,不用等厨房;只有点佛跳墙、东坡肉(动态资源,如JSP页面、数据库查询结果),才把菜单传给后厨(Tomcat)现做。分工明确后,顾客等餐更快,厨房也能专心做复杂菜品。

技术解释
  • 定义:将静态资源(.html、.jpg、.css、.js、.gif等)和动态资源(.jsp、.do、.action等)分开处理,由不同组件负责响应。
  • 核心逻辑:① 静态资源由Nginx直接读取本地文件返回,Nginx处理静态资源的并发能力强、资源消耗低;② 动态请求由Nginx转发给Tomcat,Tomcat专注执行业务逻辑(如数据库交互、API调用)。
  • 核心优势:减轻Tomcat负载,提升动态请求处理效率;Nginx处理静态资源速度比Tomcat快3-5倍,缩短页面加载时间;架构职责分离,便于单独优化和维护。
动静分离配置示例(含Gzip与缓存)
nginx 复制代码
server {
    listen 80;
    server_name www.mywebsite.com;
    charset utf-8;
    gzip on; # 启用Gzip压缩,减小静态资源传输体积

    # 动态请求(.jsp、.do、.action后缀)转发给Tomcat
    location ~ \.(jsp|do|action)$ {
        proxy_pass http://tomcat_server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_connect_timeout 30s; # 连接超时时间
        proxy_read_timeout 60s; # 读取超时时间
    }

    # 静态资源由Nginx直接处理
    location ~ \.(html|htm|gif|jpg|jpeg|css|js|bmp|swf)$ {
        root /data/www/static; # 静态文件存放根目录
        expires 30d; # 浏览器缓存30天,减少重复请求
        access_log off; # 关闭静态资源访问日志,节省磁盘IO
    }
}

二、负载均衡:Nginx分流Tomcat集群

2.1 负载均衡原理

通俗解释

餐厅生意火爆时,一个厨房忙不过来,就多开几个厨房(Tomcat集群)。迎宾员(Nginx)会看每个厨房的忙碌程度(负载情况),把新顾客引导到人少的厨房,避免某个厨房累垮(服务器过载),也不让顾客等太久(响应超时)。就算其中一个厨房出问题(服务器故障),迎宾员会直接跳过它,把顾客转到其他正常厨房,不影响生意(服务可用性)。

技术解释
  • 定义:当单台后端服务器无法承载高并发请求时,部署多台服务器组成集群,Nginx按预设策略将请求分发给集群节点,实现负载分摊。
  • 核心价值:① 提升并发处理能力,分散单台服务器压力;② 实现高可用,某节点故障时自动切换至正常节点;③ 支持横向扩展,业务增长时可直接新增节点,无需修改核心架构。
  • 核心流程:客户端 → Nginx(负载均衡器) → 集群中某台Tomcat → Nginx → 客户端。

2.2 常见负载均衡策略(适配Tomcat集群)

2.2.1 轮询(Round Robin,默认)
通俗解释

就像排队报数,顾客按顺序依次分配给每个厨房,1号厨房、2号厨房、3号厨房,然后再回到1号,循环往复。适合所有厨房规模、做菜速度都一样的情况。

技术解释
  • 原理:Nginx默认策略,请求按顺序依次分配给集群中的每台服务器,循环分发。
  • 特点:无需额外配置,请求分配均匀,无视服务器当前负载和响应时间。
  • 适用场景:集群中所有Tomcat服务器配置、性能一致,动态请求处理时间相近。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    server 192.168.10.10:8080; # Tomcat节点1
    server 192.168.10.11:8080; # Tomcat节点2
}
2.2.2 加权轮询(Weighted Round Robin)
通俗解释

给做菜快、规模大的厨房(高性能Tomcat)分配更多顾客(更高权重),比如A厨房权重3、B厨房权重1,意味着4个顾客中3个去A厨房,1个去B厨房,充分利用高性能资源。

技术解释
  • 原理:为每台服务器设置权重(weight参数),权重值越高,分配到的请求越多。
  • 特点:支持按服务器性能差异化分配请求,提升集群整体资源利用率。
  • 适用场景:Tomcat集群配置不均衡(如CPU、内存规格不同),服务器性能存在差异。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    server 192.168.10.10:8080 weight=1; # 权重1,处理1份请求
    server 192.168.10.11:8080 weight=2; # 权重2,处理2份请求
}
2.2.3 IP哈希(IP Hash)
通俗解释

给每个顾客分配一个专属"编号"(IP哈希值),同一个顾客的编号永远对应同一个厨房,确保顾客的用餐进度(登录状态、会话数据)不会丢失,不用重复点餐(重新登录)。

技术解释
  • 原理:基于客户端IP地址计算哈希值,将同一IP的所有请求固定分配给集群中的同一台服务器。
  • 特点:实现会话持久化,避免用户会话数据丢失;服务器节点变更时,仅影响部分用户请求。
  • 适用场景:需要保持用户会话的场景(如登录系统、购物车功能),避免用户频繁重新登录。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    ip_hash; # 启用IP哈希策略
    server 192.168.10.10:8080;
    server 192.168.10.11:8080;
}
2.2.4 最少连接数(Least Connections)
通俗解释

迎宾员实时查看每个厨房当前的顾客数量(活跃连接数),把新顾客引导到当前顾客最少的厨房,避免某个厨房忙到爆,其他厨房却闲置。

技术解释
  • 原理:请求分配给当前活跃连接数最少的服务器,动态平衡集群负载。
  • 特点:能根据服务器实时负载调整请求分配,避免单台服务器因长连接过载。
  • 适用场景:请求处理时间不均匀(如部分请求需复杂数据库查询,耗时较长)的场景。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    least_conn; # 启用最少连接数策略
    server 192.168.10.10:8080;
    server 192.168.10.11:8080;
}
2.2.5 最少时间算法(Least Time)
通俗解释

迎宾员记录每个厨房的出餐速度(响应时间),新顾客优先分配给出餐最快的厨房,确保顾客等待时间最短,提升用餐体验。

技术解释
  • 原理:基于服务器响应时间分配请求,将请求转发给响应时间最短或平均连接时间最短的服务器。
  • 特点:智能感知服务器响应速度,动态优化请求分配,提升用户访问体验。
  • 要求:Nginx 1.15.3及以上版本支持。
  • 适用场景:对响应速度要求高的场景(如实时查询、金融交易系统)。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    least_time header; # 基于响应头判断响应时间
    server 192.168.10.10:8080;
    server 192.168.10.11:8080;
}
2.2.6 一致性哈希(Consistent Hashing)
通俗解释

给每个厨房和顾客点的菜品(如URL)分配一个固定编号,把这些编号按顺序排成一个圈(哈希环),菜品编号靠近哪个厨房编号,就由哪个厨房制作。就算某个厨房暂停服务(服务器故障),也只有附近编号的菜品会重新分配,不会影响所有顾客。

技术解释
  • 原理:将服务器和请求参数(如URL、Cookie)映射到哈希环上,服务器节点变更时,仅影响哈希环上相邻的部分请求,而非全部分配。
  • 特点:减少服务器节点变更时的请求重新分配,降低缓存失效概率。
  • 要求:需安装第三方模块(如ngx_http_upstream_hash_module)。
  • 适用场景:缓存敏感场景(如Tomcat集成Redis缓存),减少缓存穿透和雪崩风险。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    hash $request_uri consistent; # 基于URL哈希,启用一致性策略
    server 192.168.10.10:8080;
    server 192.168.10.11:8080;
}
2.2.7 备份服务器配置
通俗解释

专门预留一个"备用厨房",只有当所有主厨房都忙不过来或出问题时,才启用备用厨房,确保生意不中断。

技术解释
  • 原理:配置备份服务器(backup参数),仅当所有主服务器不可用时,备份服务器才接收请求。
  • 适用场景:对可用性要求极高的场景,进一步提升服务容错能力。
  • 配置片段:
nginx 复制代码
upstream tomcat_cluster {
    server 192.168.10.10:8080 weight=1;
    server 192.168.10.11:8080 weight=2;
    server 192.168.10.12:8080 backup; # 备份服务器,主节点故障时生效
}

2.3 负载均衡配置示例(带故障转移)

生产环境需添加故障容错配置,避免单台Tomcat故障影响服务:

nginx 复制代码
upstream tomcat_cluster {
    ip_hash;
    # max_fails=3:连续3次请求失败标记为不可用;fail_timeout=30s:30秒后重新检测
    server 192.168.10.10:8080 weight=1 max_fails=3 fail_timeout=30s;
    server 192.168.10.11:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.10.12:8080 backup;
}

# 关联负载均衡的Nginx服务配置
server {
    listen 80;
    server_name www.mywebsite.com;
    charset utf-8;
    gzip on;

    # 动态请求转发
    location ~ \.(jsp|do|action)$ {
        proxy_pass http://tomcat_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 静态资源处理
    location ~ \.(html|htm|gif|jpg|jpeg|css|js|bmp|swf)$ {
        root /data/www/static;
        expires 30d;
        access_log off;
    }
}

2.4 高可用与健康检查

通俗解释
  • 被动检查:迎宾员发现某个厨房连续几次没接订单(请求失败),就暂时不给它派单,过一会儿再试(重新检测),避免顾客白等。
  • 主动检查:迎宾员每隔一段时间就去每个厨房看看是否正常营业(定时探测),提前发现问题并暂停派单,不用等顾客反馈。
技术解释
  • 被动健康检查(Nginx开源版默认):通过max_fails(允许失败的请求次数)和fail_timeout(失败后暂停转发时间)参数,仅在请求失败时标记服务器不可用。
  • 主动健康检查:定时探测后端服务器端口和服务状态,需通过Nginx Plus(商业版)或第三方模块(如nginx_upstream_check_module)实现。
  • 核心价值:自动识别故障节点并隔离,故障恢复后自动重新纳入集群,提升服务高可用性。

三、后端Tomcat准备:部署动态应用

3.1 Tomcat概述与运行原理

通俗解释

Tomcat就像餐厅的"专业厨房",专门负责制作需要现做的"大菜"(动态内容)。顾客点的菜(动态请求)经迎宾员(Nginx)传到厨房,厨师(Servlet)按菜单(JSP代码)制作,做好后再经迎宾员端给顾客。厨房内部有明确分工:有人负责备菜(Web容器)、有人负责烹饪(Servlet容器)、有人负责处理特殊菜品(JSP容器),效率更高。

技术解释
  • 概述:Tomcat是轻量级Web应用服务器,同时也是Servlet/JSP容器,用于托管基于Java技术的Web应用(如Servlet、JSP、Spring MVC)。
  • 核心功能:接收HTTP请求、按URL映射分发至对应Web应用、执行Servlet/JSP代码、生成动态响应并返回。
  • 运行流程:① Nginx转发请求至Tomcat 8080端口;② Web容器接收请求并解析类型;③ JSP容器将JSP代码翻译成Servlet代码并编译为字节码;④ Servlet容器(Catalina)执行字节码,处理业务逻辑(如数据库交互、API调用);⑤ 响应经Web容器封装后原路返回。

3.2 Tomcat核心配置文件

通俗解释

Tomcat的配置文件就像厨房的"规章制度":① 主规则(server.xml)规定厨房的出入口(端口)、分工架构(引擎、虚拟主机);② 通用规则(web.xml)规定所有菜品的默认制作标准(MIME类型、默认Servlet);③ 资源规则(context.xml)规定厨房的共用工具(数据源、连接池);④ 权限规则(tomcat-users.xml)规定谁能进入厨房管理后台(Manager App)。

技术解释

Tomcat核心配置文件集中在/usr/local/tomcat/conf目录,功能如下:

配置文件 核心作用
conf/server.xml 主配置文件,定义端口(Connector)、引擎(Engine)、虚拟主机(Host)、应用上下文(Context)等核心组件
conf/web.xml 全局Web应用配置,定义默认Servlet、MIME类型映射、错误页面等通用规则
conf/context.xml 应用上下文配置,可配置数据源(JNDI)、Session持久化、资源链接等全局资源
conf/tomcat-users.xml 用户权限配置,定义Tomcat管理后台(Manager App、Admin Console)的用户、角色和密码
应用内WEB-INF/web.xml 单个Web应用的专属配置,定义该应用的Servlet、过滤器(Filter)、监听器(Listener)等

3.3 Tomcat安装与启动(依赖JDK)

通俗解释

要开厨房(Tomcat),得先有厨房设备(JDK),否则厨师(Java代码)无法工作。安装步骤就是:① 准备好工作环境(关闭防火墙,避免外部干扰);② 安装设备(JDK)并调试好(配置环境变量);③ 布置厨房(解压Tomcat);④ 启动厨房(执行启动命令),检查出入口(端口)是否正常开放。

技术解释

Tomcat运行依赖JDK(Java开发工具包),部署步骤如下:

  1. 环境准备:关闭防火墙和SELinux,避免端口被拦截;
bash 复制代码
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
  1. 安装JDK并配置环境变量:
bash 复制代码
# 解压JDK到指定目录
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
# 配置环境变量
vim /etc/profile

添加以下内容:

bash 复制代码
export JAVA_HOME=/usr/local/jdk1.8.0_91 # JDK安装目录
export JRE_HOME=${JAVA_HOME}/jre # JRE目录
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib # 类路径,指定JVM查找类文件的路径
export PATH=${JAVA_HOME}/bin:$PATH # 将JDK二进制目录加入系统PATH,全局可用Java命令

生效并验证:

bash 复制代码
source /etc/profile
java -version # 显示JDK版本即安装成功
  1. 安装并启动Tomcat:
bash 复制代码
# 解压Tomcat
tar zxvf apache-tomcat-8.5.35.tar.gz -C /usr/local/
mv /usr/local/apache-tomcat-8.5.35 /usr/local/tomcat # 简化目录名

# 启动/停止命令
/usr/local/tomcat/bin/startup.sh # 启动(调用catalina.sh start)
/usr/local/tomcat/bin/shutdown.sh # 关闭(调用catalina.sh stop)

# 验证:查看8080端口是否监听(Tomcat默认HTTP端口)
netstat -natp | grep 8080
# 查看Tomcat进程是否运行
ps -aux | grep java

3.4 Tomcat多实例端口配置(集群避免冲突)

通俗解释

开多个厨房(多台Tomcat)时,每个厨房的出入口(端口)不能一样,否则顾客会走错门(端口冲突)。需要给每个厨房分配独立的关闭门(8005→8006)、点餐口(8080→8081)、配菜口(8009→8010),确保各自正常运营。

技术解释

部署多台Tomcat时,需修改核心端口避免冲突,步骤如下:

  1. 复制Tomcat实例:
bash 复制代码
cp -a /usr/local/tomcat /usr/local/tomcat2 # 复制现有Tomcat目录,保留权限和配置
  1. 编辑tomcat2server.xml,修改3个核心端口:
bash 复制代码
vim /usr/local/tomcat2/conf/server.xml
  • 服务器关闭端口(Server端口):80058006(用于接收关闭命令)
xml 复制代码
<Server port="8006" shutdown="SHUTDOWN">
  • HTTP请求端口(Connector端口):80808081(用于接收HTTP请求)
xml 复制代码
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
  • AJP协议端口(AJP Connector端口):80098010(用于与其他Web服务器通信)
xml 复制代码
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
  1. 启动tomcat2
bash 复制代码
/usr/local/tomcat2/bin/startup.sh

3.5 Tomcat数据源配置(JNDI连接池)

通俗解释

厨房做菜需要频繁用刀、锅等工具(数据库连接),如果每次做菜都重新找工具(创建连接),效率很低。可以准备一个"工具架"(连接池),提前放好足够的工具,厨师要用时直接拿,用完放回,不用重复找,提升做菜效率。

技术解释
  • 定义:通过JNDI(Java命名和目录接口)配置数据库连接池,由Tomcat统一管理数据库连接,避免应用频繁创建和关闭连接,提升性能和可维护性。
  • 核心优势:连接池复用数据库连接,减少连接创建开销;数据源配置与应用解耦,便于运维统一管理;支持动态调整连接数,适配不同负载场景。
  • 配置步骤:
  1. 编辑context.xml文件:
bash 复制代码
vim /usr/local/tomcat/conf/context.xml
  1. 添加数据源配置(以MySQL为例):
xml 复制代码
<Resource 
    name="jdbc/MyDB" # 数据源名称,应用通过该名称获取连接
    auth="Container" # 认证方式,由Tomcat容器管理
    type="javax.sql.DataSource" # 资源类型,数据源接口
    maxActive="20" # 最大活跃连接数
    maxIdle="10" # 最大空闲连接数
    maxWait="10000" # 最大等待时间(毫秒),超过则抛出异常
    username="root" # 数据库用户名
    password="123456" # 数据库密码
    driverClassName="com.mysql.cj.jdbc.Driver" # MySQL驱动类全路径
    url="jdbc:mysql://localhost:3306/test" # 数据库连接URL(指定数据库地址和库名)
/>
  1. 应用代码中获取数据源:
java 复制代码
// 初始化JNDI上下文
Context initCtx = new InitialContext();
// 通过名称查找数据源
DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/MyDB");
// 从连接池获取连接
Connection conn = ds.getConnection();
// 执行SQL操作...
// 用完后关闭连接(归还至连接池,而非真正关闭)
conn.close();

四、部署实战:Nginx反向代理+负载均衡+动静分离整合Tomcat

4.1 环境规划

角色 IP地址 端口 核心功能
Nginx负载均衡器 192.168.10.20 80 反向代理、负载均衡、静态资源处理
Tomcat节点1 192.168.10.10 8080 处理动态请求(JSP/Servlet)
Tomcat节点2 192.168.10.11 8081 处理动态请求(JSP/Servlet)
静态资源存储 192.168.10.20 - 存放HTML、图片、CSS等静态文件

4.2 Nginx完整部署(编译安装)

通俗解释

安装Nginx就像搭建餐厅的"迎宾区":① 先准备好搭建材料(编译依赖);② 创建专门的管理员(Nginx用户)负责迎宾区运营;③ 搭建迎宾区框架(解压并编译Nginx),同时配备必要功能(启用SSL、Gzip等模块);④ 制定运营规则(系统服务配置),确保迎宾区能正常启动、停止,且开机自动运行。

技术解释

若未安装Nginx,执行以下编译安装步骤(启用核心模块):

bash 复制代码
# 安装编译依赖(pcre用于正则匹配,zlib用于Gzip压缩,openssl用于SSL加密)
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
# 创建Nginx专用用户(无登录权限,仅用于运行Nginx进程,提升安全性)
useradd -M -s /sbin/nologin nginx
# 解压Nginx安装包(以1.20.2为例)
cd /opt
tar zxvf nginx-1.20.2.tar.gz
cd nginx-1.20.2
# 配置编译参数(启用核心功能模块)
./configure \
--prefix=/usr/local/nginx \ # 指定安装目录
--user=nginx \ # 指定运行用户
--group=nginx \ # 指定运行用户组
--with-file-aio \ # 启用文件异步I/O,提升高并发处理能力
--with-http_stub_status_module \ # 启用状态统计模块,可查看Nginx运行状态
--with-http_gzip_static_module \ # 启用Gzip静态压缩模块
--with-http_ssl_module \ # 启用SSL加密模块,支持HTTPS
--with-stream # 启用Stream模块,支持4层TCP/UDP负载均衡
# 编译并安装(make编译源代码,make install复制文件到安装目录)
make && make install
# 创建系统服务,支持systemctl命令管理
vim /lib/systemd/system/nginx.service

添加系统服务配置:

ini 复制代码
[Unit]
Description=Nginx Web Server # 服务描述
After=network.target # 网络服务启动后再启动Nginx

[Service]
Type=forking # 后台运行模式(fork子进程)
PIDFile=/usr/local/nginx/logs/nginx.pid # PID文件路径,用于识别主进程
ExecStart=/usr/local/nginx/sbin/nginx # 启动命令
ExecReload=/bin/kill -s HUP $MAINPID # 重载配置命令(不停止服务)
ExecStop=/bin/kill -s QUIT $MAINPID # 停止命令
PrivateTmp=true # 为服务分配独立临时目录,提升安全性

[Install]
WantedBy=multi-user.target # 多用户模式下开机自启

启动Nginx并设置开机自启:

bash 复制代码
chmod 754 /lib/systemd/system/nginx.service # 设置服务文件权限
systemctl daemon-reload # 重新加载系统服务配置
systemctl start nginx # 启动Nginx
systemctl enable nginx # 设置开机自启

4.3 Nginx完整配置(整合所有功能)

编辑nginx.conf,实现"反向代理+负载均衡+动静分离"一体化配置:

nginx 复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;

    # 1. 定义Tomcat集群(加权轮询+故障转移+备份节点)
    upstream tomcat_cluster {
        server 192.168.10.10:8080 weight=1 max_fails=3 fail_timeout=30s;
        server 192.168.10.11:8081 weight=2 max_fails=3 fail_timeout=30s;
        server 192.168.10.12:8080 backup; # 备份节点
    }

    # 2. Nginx服务配置
    server {
        listen 80;
        server_name www.mywebsite.com;
        charset utf-8;
        gzip on; # 启用Gzip压缩

        # 3. 动静分离:静态资源本地处理
        location ~ \.(html|htm|gif|jpg|jpeg|css|js|bmp|swf)$ {
            root /data/www/static; # 静态资源目录
            expires 30d; # 缓存30天
            access_log off; # 关闭日志
        }

        # 4. 反向代理+负载均衡:动态请求转发
        location ~ \.(jsp|do|action)$ {
            proxy_pass http://tomcat_cluster; # 指向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_connect_timeout 30s; # 连接超时时间
            proxy_read_timeout 60s; # 读取超时时间
        }

        # 5. 静态图片单独配置(缓存10天)
        location ~ \.(jpg|png|jpeg)$ {
            root /data/www/static/img;
            expires 10d;
            access_log off;
        }
    }
}

4.4 Tomcat应用部署(测试动态页面)

在两台Tomcat的webapps/ROOT目录下,分别创建测试JSP页面,验证负载均衡:

  1. Tomcat节点1(192.168.10.10:8080):
bash 复制代码
cd /usr/local/tomcat/webapps/ROOT/
mv index.jsp index.jsp.bak # 备份默认页面
vim index.jsp

添加测试内容:

jsp 复制代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP Test1 Page</title></head>
<body>
<% out.println("动态页面 1 - Tomcat Node1: 192.168.10.10:8080"); %>
</body>
</html>

重启Tomcat1:

bash 复制代码
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
  1. Tomcat节点2(192.168.10.11:8081):
bash 复制代码
cd /usr/local/tomcat2/webapps/ROOT/
mv index.jsp index.jsp.bak
vim index.jsp

添加测试内容:

jsp 复制代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP Test2 Page</title></head>
<body>
<% out.println("动态页面 2 - Tomcat Node2: 192.168.10.11:8081"); %>
</body>
</html>

重启Tomcat2:

bash 复制代码
/usr/local/tomcat2/bin/shutdown.sh
/usr/local/tomcat2/bin/startup.sh

4.5 功能验证(浏览器+命令行)

测试1:静态页面访问
  • 浏览器输入http://www.mywebsite.com,显示静态页面内容(如"这是静态页面");
  • 命令行测试:curl -I http://www.mywebsite.com,返回200状态码,说明静态资源处理正常。
测试2:静态图片访问
  • 浏览器输入http://www.mywebsite.com/img/test.jpg(需提前放入静态目录),正常显示图片;
  • 查看响应头,包含Cache-Control: max-age=864000(10天缓存),说明缓存配置生效。
测试3:反向代理与负载均衡验证
  • 浏览器访问http://www.mywebsite.com/test.jsp,多次刷新,内容按权重1:2显示"Node1"和"Node2";
  • 命令行测试:curl http://www.mywebsite.com/test.jsp,多次执行,交替返回两台Tomcat的动态内容;
  • 故障转移测试:停止Tomcat1(/usr/local/tomcat/bin/shutdown.sh),刷新页面仅显示"Node2";再停止Node2,备份节点自动启用。
测试4:请求头传递验证

查看Tomcat访问日志(/usr/local/tomcat/logs/localhost_access_log.*.txt),可看到日志中记录的是用户真实IP(而非Nginx服务器IP),说明X-Real-IP配置生效。

总结

反向代理、负载均衡、动静分离三项技术通常协同使用,构建高性能、高可用的Web架构,其核心流程如下:

  1. 用户访问www.mywebsite.com → Nginx(反向代理)作为统一入口;
  2. Nginx根据请求类型分流:
    • 静态资源(图片/CSS/JS)→ Nginx直接返回(动静分离),速度极快;
    • 动态请求(JSP/接口)→ Nginx按策略选择Tomcat节点(负载均衡),转发请求;
  3. Tomcat处理业务逻辑(如数据库查询、API调用),生成动态页面,经Nginx返回给用户。

Nginx与Tomcat各司其职、强强联合:Nginx负责"接待分流",Tomcat负责"烹饪大餐",既保证了网站的访问速度,又提升了服务的稳定性和扩展性,可直接用于中小型动态Web应用的生产部署。

相关推荐
涔溪27 分钟前
通过Nginx反向代理配置连接多个后端服务器
vue.js·nginx
S9037845972 小时前
为什么取模在除数等于2^n的时候可以用按位与替代?
java·tomcat·计算机外设·hibernate
z***94842 小时前
Linux下安装Nginx服务及systemctl方式管理nginx详情
linux·运维·nginx
默恋~微凉3 小时前
Nginx(十一)——反向代理与负载均衡
运维·nginx·负载均衡
可丷乐3 小时前
nginx常用命令
nginx
木童6624 小时前
Nginx 深度解析:反向代理与负载均衡、后端Tomcat
linux·运维·nginx
摇滚侠5 小时前
2025最新 SpringCloud 教程,Nacos-注册中心 @LoadBalanced 注解式负载均衡,笔记11
笔记·spring cloud·负载均衡
0wioiw05 小时前
跨网络互联技术(Nginx反向代理)
服务器·网络·nginx
先生沉默先7 小时前
Nginx 反向代理学习:单端口统一访问多服务
学习·nginx·arcgis