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代理对外提供访问,配置如下:
- 编辑Nginx主配置文件:
bash
vim /usr/local/nginx/conf/nginx.conf
- 添加代理配置(包含完整请求头传递):
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;
}
}
- 验证配置并生效:
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开发工具包),部署步骤如下:
- 环境准备:关闭防火墙和SELinux,避免端口被拦截;
bash
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
- 安装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版本即安装成功
- 安装并启动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时,需修改核心端口避免冲突,步骤如下:
- 复制Tomcat实例:
bash
cp -a /usr/local/tomcat /usr/local/tomcat2 # 复制现有Tomcat目录,保留权限和配置
- 编辑
tomcat2的server.xml,修改3个核心端口:
bash
vim /usr/local/tomcat2/conf/server.xml
- 服务器关闭端口(Server端口):
8005→8006(用于接收关闭命令)
xml
<Server port="8006" shutdown="SHUTDOWN">
- HTTP请求端口(Connector端口):
8080→8081(用于接收HTTP请求)
xml
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
- AJP协议端口(AJP Connector端口):
8009→8010(用于与其他Web服务器通信)
xml
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
- 启动
tomcat2:
bash
/usr/local/tomcat2/bin/startup.sh
3.5 Tomcat数据源配置(JNDI连接池)
通俗解释
厨房做菜需要频繁用刀、锅等工具(数据库连接),如果每次做菜都重新找工具(创建连接),效率很低。可以准备一个"工具架"(连接池),提前放好足够的工具,厨师要用时直接拿,用完放回,不用重复找,提升做菜效率。
技术解释
- 定义:通过JNDI(Java命名和目录接口)配置数据库连接池,由Tomcat统一管理数据库连接,避免应用频繁创建和关闭连接,提升性能和可维护性。
- 核心优势:连接池复用数据库连接,减少连接创建开销;数据源配置与应用解耦,便于运维统一管理;支持动态调整连接数,适配不同负载场景。
- 配置步骤:
- 编辑
context.xml文件:
bash
vim /usr/local/tomcat/conf/context.xml
- 添加数据源配置(以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(指定数据库地址和库名)
/>
- 应用代码中获取数据源:
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页面,验证负载均衡:
- 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
- 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架构,其核心流程如下:
- 用户访问
www.mywebsite.com→ Nginx(反向代理)作为统一入口; - Nginx根据请求类型分流:
- 静态资源(图片/CSS/JS)→ Nginx直接返回(动静分离),速度极快;
- 动态请求(JSP/接口)→ Nginx按策略选择Tomcat节点(负载均衡),转发请求;
- Tomcat处理业务逻辑(如数据库查询、API调用),生成动态页面,经Nginx返回给用户。
Nginx与Tomcat各司其职、强强联合:Nginx负责"接待分流",Tomcat负责"烹饪大餐",既保证了网站的访问速度,又提升了服务的稳定性和扩展性,可直接用于中小型动态Web应用的生产部署。