文章目录
- 前言
- 一、反向代理
-
- [1.1 反向代理原理](#1.1 反向代理原理)
- [1.2 实验配置示例](#1.2 实验配置示例)
- 二、负载均衡
-
- [2.1 负载均衡基本原理](#2.1 负载均衡基本原理)
- [2.2 常见负载均衡策略](#2.2 常见负载均衡策略)
-
- [2.2.1 轮询(Round Robin)(最常用)](#2.2.1 轮询(Round Robin)(最常用))
- [2.2.2 最少连接数(Least Connections)](#2.2.2 最少连接数(Least Connections))
- [2.2.3 IP 哈希(IP Hash)](#2.2.3 IP 哈希(IP Hash))
- [2.2.4 加权轮询(Weighted Round Robin)](#2.2.4 加权轮询(Weighted Round Robin))
- [2.2.5 最少时间算法(Least Time)](#2.2.5 最少时间算法(Least Time))
- [2.2.6 一致性哈希(Consistent Hashing)](#2.2.6 一致性哈希(Consistent Hashing))
- [2.3 配置示例](#2.3 配置示例)
-
- [2.3.1 基础轮询配置](#2.3.1 基础轮询配置)
- [2.3.2 带权重和故障转移的配置](#2.3.2 带权重和故障转移的配置)
- [2.4 高可用与健康检查](#2.4 高可用与健康检查)
- [2.5 负载均衡总结](#2.5 负载均衡总结)
- [三、Tomcat 后端服务器](#三、Tomcat 后端服务器)
-
- [3.1 Tomcat 概述](#3.1 Tomcat 概述)
- [3.2 运行原理](#3.2 运行原理)
- [3.3 主要配置文件](#3.3 主要配置文件)
- [3.4 调用应用接口](#3.4 调用应用接口)
- [3.5 调用数据库接口](#3.5 调用数据库接口)
- [3.6 Tomcat 部署步骤](#3.6 Tomcat 部署步骤)
-
- [3.6.1 环境准备](#3.6.1 环境准备)
- [3.6.2 JDK 安装与环境变量配置](#3.6.2 JDK 安装与环境变量配置)
- [3.6.3 安装与启动 Tomcat](#3.6.3 安装与启动 Tomcat)
- [3.7 Tomcat总结](#3.7 Tomcat总结)
- [四、Nginx + Tomcat 实战:反向代理与负载均衡](#四、Nginx + Tomcat 实战:反向代理与负载均衡)
-
- [4.1 环境规划](#4.1 环境规划)
- [4.2 Nginx 负载均衡器部署](#4.2 Nginx 负载均衡器部署)
- [4.3 Tomcat 应用服务器部署](#4.3 Tomcat 应用服务器部署)
- [4.4 动静分离配置](#4.4 动静分离配置)
-
- [4.4.1 Tomcat1 配置](#4.4.1 Tomcat1 配置)
- [4.4.2 Tomcat2 配置](#4.4.2 Tomcat2 配置)
- [4.4.3 Nginx 配置](#4.4.3 Nginx 配置)
- [4.5 效果测试](#4.5 效果测试)
- 总结
前言
在现代 Web 架构中,Nginx 作为高性能的反向代理和负载均衡服务器,被广泛应用于生产环境中。它不仅可以有效提升系统的并发处理能力、可用性和扩展性,还能实现动静分离、请求分发等关键功能。本文将从原理到实践,系统介绍 Nginx 的反向代理与负载均衡机制,并结合 Tomcat 后端服务器的部署与配置,提供一个完整的实战指南。
一、反向代理
1.1 反向代理原理
反向代理是Nginx的核心功能之一,其工作原理如下:
- 用户请求首先到达 Nginx 服务器
- Nginx根据配置将请求转发给后端应用服务器/业务服务器(如Tomcat、Node.js、Spring Boot等)
- 后端:php python java(java后端 、tomcat 、微服务)
- Nginx 在这一过程中充当"中转站"的角色,客户端并不知道真正提供服务的后端服务器是哪一台,从而实现了请求的转发与隐藏后端服务器的作用

基本流程如下:
客户端 → Nginx → 后端服务器集群
1.2 实验配置示例
要配置 Nginx 作为反向代理,需编辑 nginx.conf
文件,在 server
块中添加如下配置:
nginx
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1(后端IP):8080; # 将请求转发至后端8080端口
==========================================================
proxy_set_header Host $host; # 保留原始 Host 头信息
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
==========================================================
}
}
保存配置后,执行以下命令重新加载 Nginx:
bash
nginx -s reload
或者
systemctl reload nginx
此时访问 http://localhost/
,实际请求将由 Nginx 转发至 http://127.0.0.1:8080/
。
二、负载均衡
2.1 负载均衡基本原理
负载均衡(Load Balancing)是 Nginx 的核心功能之一,通过将客户端请求分发到多台后端服务器,显著提升系统的并发处理能力、可用性和稳定性。
主要优势包括:
- 提升性能:分散单台服务器压力;
- 高可用性:某台服务器故障时,自动将请求转发至其他正常节点;
- 良好的扩展性:可灵活增删后端服务器节点。

2.2 常见负载均衡策略
Nginx 支持多种负载均衡算法,可根据实际业务场景选择合适的策略。
2.2.1 轮询(Round Robin)(最常用)
轮询算法是 Nginx 的默认分流算法。它按顺序将请求依次分配给每一台后端服务器,直到最后一台服务器,然后重新从第一台服务器开始。这种方法简单且均匀地分配了流量。
数据流向:每个请求依次被分配到下一个服务器。假设有三台服务器(Server A、Server B、Server C),第一个请求被分配到 Server A,第二个请求分配到 Server B,第三个请求分配到 Server C,第四个请求又回到 Server A,依此类推。
特点:
- Nginx默认的负载均衡算法
- 请求按顺序均匀分配到每台后端服务器,无视服务器的当前负载和响应时间
- 简单高效,适合服务器性能相近的场景
配置示例:
nginx
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.2.2 最少连接数(Least Connections)
最少连接数算法将请求分配给当前活动连接数最少的服务器。这种算法适用于请求处理时间不均匀的情况,可以有效平衡服务器的负载。
数据流向:每个请求被分配到当前连接数最少的服务器。例如,Server A 有 2 个连接,Server B 有 5 个连接,新的请求会被分配到 Server A。
特点:
- 将请求分配给当前活动连接数最少的服务器
- 动态均衡负载,适用于请求处理时间不一的场景
- 有效避免服务器过载
配置示例:
nginx
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.2.3 IP 哈希(IP Hash)
IP 哈希算法通过计算客户端 IP 地址的哈希值,将请求始终分配给同一台服务器。适用于需要将特定客户端的请求固定在同一台服务器上的场景。
数据流向:每个客户端的 IP 地址被哈希计算,然后根据哈希值将请求固定分配到某一台服务器。假设客户端 X 的哈希值指向 Server A,客户端 Y 的哈希值指向 Server B,则无论多少次请求,X 的请求总是流向 Server A,Y 的请求总是流向 Server B。
特点:
- 基于客户端IP地址计算哈希值
- 同一个客户端总是被分配到同一台服务器,有助于会话保持
配置示例:
nginx
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.2.4 加权轮询(Weighted Round Robin)
加权轮询算法允许为每台服务器设置权重,权重越大的服务器将会获得更多的请求。适用于服务器性能不均衡的情况。
数据流向:根据服务器设置的权重值分配请求。假设 Server A 权重为 3,Server B 权重为 1,则 4 个请求中,3 个会被分配到 Server A,1 个会被分配到 Server B。
特点:
- 允许为每台服务器设置权重值
- 权重越高的服务器获得更多请求
- 适合服务器性能不均衡的环境
配置示例:
nginx
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=1;
server backend3.example.com weight=2;
}
2.2.5 最少时间算法(Least Time)
最少时间算法基于请求的响应时间,将请求分配给响应时间最短的服务器。这种算法在 Nginx 1.15.3 及以后版本中可用,适用于需要最大化响应速度的场景。
数据流向:每个请求分配到响应时间最短或平均连接时间最短的服务器。假设 Server A 的响应时间较快,Server B 较慢,则新的请求更可能流向 Server A。
特点:
- 基于服务器响应时间进行智能分配
- 将请求分配给响应时间最短的服务器,适用于对响应速度要求较高的场景
- Nginx 1.15.3及以上版本支持
- 进一步优化了最少连接算法,适用于高负载环境下的动态负载均衡
配置示例:
nginx
upstream backend {
least_time header;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.2.6 一致性哈希(Consistent Hashing)
一致性哈希将服务器和请求的键(如URL)映射到一个哈希环上,当集群中某台服务器故障时,只有部分请求会重新分配到其他服务器,而不是全部重新分配(IP哈希会全部分配,因为它是计算出哈希值后取余)。这在缓存等场景中非常有用。
数据流向:根据请求的某个特定参数(如 URL、Cookie 或其他 Header),进行哈希计算,将请求分配到哈希值对应的服务器。假设 Server A 和 Server B,参数 "foo" 的哈希值指向 Server A,参数 "bar" 的哈希值指向 Server B,则 "foo" 请求总是流向 Server A,"bar" 请求总是流向 Server B。
特点:
- 基于特定参数(如URL)计算哈希值,服务器节点变动时仅影响部分请求
- 适应服务器节点变动,减少请求的重新分配,适合缓存敏感的场景
- 需要第三方模块支持
配置示例:(需要第三方模块如ngx_http_upstream_hash_module
)
nginx
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.3 配置示例
2.3.1 基础轮询配置
nginx
http {
upstream backend {
server 192.168.0.101;
server 192.168.0.102;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
2.3.2 带权重和故障转移的配置
nginx
upstream backend {
server 192.168.0.101 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.0.102 weight=1 max_fails=3 fail_timeout=30s;
}
max_fails
表示允许失败的次数,fail_timeout
表示失败后暂停转发的时间。
2.4 高可用与健康检查
Nginx 开源版自带被动健康检查,仅在请求失败时标记服务器不可用。如需主动健康检查(定时探测后端状态),可选用:
- Nginx Plus 版本;
- 第三方模块如
nginx_upstream_check_module
。
2.5 负载均衡总结
Nginx 负载均衡就是通过反向代理把客户端请求按策略分配到多台后端服务器,实现高性能、高可用、可扩展的服务访问。
三、Tomcat 后端服务器
3.1 Tomcat 概述
Tomcat 是一个轻量级的 Web 应用服务器(Web Server + Servlet Container),也是一个 Servlet 容器,主要用于托管基于 Servlet、JSP、Spring MVC 等技术的 Java Web 应用。
主要功能包括:
- 接收 HTTP 请求(内置了一个简单的 HTTP 服务器)
- 将请求分发给对应的 Web 应用(基于 URL 映射)
- 执行 Servlet / JSP 并生成响应
- 返回 HTTP 响应给客户端
换句话说,Tomcat 是一个 Java Web 应用运行环境,可以托管基于 Servlet、JSP、Spring MVC、Spring Boot(war 部署)等的应用。
3.2 运行原理
1、请求入口与代理
- 用户通过浏览器发起请求(如访问网站),首先由Nginx服务器(监听80端口)接收。
- Nginx作为反向代理,将请求转发至Tomcat的8080端口(Tomcat默认服务端口)。
2、Web容器处理请求
- Tomcat的Web容器接收转发后的请求,解析请求类型(例如识别到需要处理index.jsp动态页面)。
- 容器根据URL映射确定对应的Web应用资源。
3、JSP到Servlet的转换
- JSP容器将index.jsp文件中的Java代码(如<% ... %>标签)翻译成完整的Servlet代码(本质是一个Java类)。
- 此步骤会生成Servlet的.java文件,并编译为.class字节码文件(仅首次请求或修改时触发)。
4、Servlet执行与业务逻辑
- Servlet容器(如Tomcat中的Catalina)加载并执行编译后的Servlet。
- Servlet处理业务逻辑,可能包含:
- 调用API接口(如与淘宝/京东等第三方服务交互);
- 连接MySQL数据库(执行查询或更新操作);
- 生成动态内容(如HTML响应)。
5、响应返回客户端
- Servlet将处理结果返回给Web容器,容器封装为HTTP响应。
- 响应通过Nginx原路返回至用户浏览器,完成整个流程。

3.3 主要配置文件
Tomcat 的核心配置文件主要有:
文件 | 作用 |
---|---|
conf/server.xml |
Tomcat 的主配置文件,定义 Connector (端口、协议)、Engine 、Host 、Context 等 |
conf/web.xml |
全局的 Web 应用默认配置(比如默认的 MIME 映射、默认 Servlet) |
context.xml |
定义 Web 应用级别的配置,如数据源(JNDI)、Session 配置 |
tomcat-users.xml |
用户、角色和安全相关配置,用于 Manager App、Admin Console 登录 |
应用内的 WEB-INF/web.xml |
每个 Web 应用自己的 Servlet、Filter、Listener 配置 |
3.4 调用应用接口
应用接口:Tomcat 负责将请求转交给指定的 Servlet 或框架(如 Spring MVC);
当你的应用部署到 Tomcat 中时,Tomcat 会:
- 在启动时加载你的
web.xml
或注解(如@WebServlet
) - 创建并初始化 Servlet
- 当有 HTTP 请求时,将请求参数封装成
HttpServletRequest
- 调用你的 Servlet 或框架(如 Spring MVC 的 DispatcherServlet)
- 你的业务代码处理完成后返回
HttpServletResponse
也就是说,Tomcat 并不关心业务逻辑,只负责把请求转给你的代码执行。
3.5 调用数据库接口
数据库接口:可通过 JNDI 数据源实现数据库连接池的配置与管理,提升性能与可维护性。
Tomcat 提供了 JNDI 数据源 支持,让应用能复用数据库连接池:
-
配置数据源
在
context.xml
或某个应用的META-INF/context.xml
:xml<Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource" maxActive="20" maxIdle="10" maxWait="10000" username="root" password="123456" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/test"/>
-
应用代码获取数据源
javaContext initCtx = new InitialContext(); DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/MyDB"); Connection conn = ds.getConnection(); // 执行 SQL ...
这样做的好处:
- 连接池由 Tomcat 管理,性能更好
- 数据源配置与应用解耦,方便运维
3.6 Tomcat 部署步骤
3.6.1 环境准备
关闭防火墙 与增强功能
bash
systemctl stop firewalld
setenforce 0
3.6.2 JDK 安装与环境变量配置
bash
# 配置JDK,现在系统基本自带openJDK
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile
添加以下内容:
bash
export JAVA_HOME=/usr/local/jdk1.8.0_91
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
执行 source /etc/profile
使配置生效。
bash
# 使配置生效
source /etc/profile
# 验证安装
java -version
3.6.3 安装与启动 Tomcat
bash
#先下载安装包,然后再解压
tar zxvf apache-tomcat-8.5.35.tar.gz
#修改服务名字
mv apache-tomcat-8.5.35 /usr/local/tomcat
# 启动/停止命令
/usr/local/tomcat/bin/startup.sh # 启动
/usr/local/tomcat/bin/shutdown.sh # 关闭
# 验证端口
netstat -ntap | grep 8080
# 查看进程
ps -aux|grep java
3.7 Tomcat总结
- 本质:Tomcat 是 Java Web 应用的运行容器,负责接收 HTTP 请求、调用 Servlet、返回响应
- 原理:Connector 监听请求 → Mapper 分发 → Servlet 执行 → 返回响应
- 配置文件:server.xml(端口、Host)、web.xml(全局)、context.xml(数据源)、tomcat-users.xml(用户)
- 应用接口调用:Tomcat 把请求交给你的 Servlet/框架
- 数据库接口调用:通过 JNDI 数据源或自己管理 JDBC 连接
四、Nginx + Tomcat 实战:反向代理与负载均衡
4.1 环境规划
- Nginx 负载均衡器:192.168.10.110:80
- Tomcat 服务器1:192.168.10.123:8080
- Tomcat 服务器2:192.168.10.123:8081
4.2 Nginx 负载均衡器部署
如已安装可跳过,否则执行:
bash
# 安装依赖与编译安装
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
useradd -M -s /sbin/nologin nginx
cd /opt
tar zxvf nginx-1.20.2.tar.gz -C /opt/
cd nginx-1.20.2/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-file-aio \ #启用文件修改支持
--with-http_stub_status_module \ #启用状态统计
--with-http_gzip_static_module \ #启用 gzip静态压缩
--with-http_flv_module \ #启用 flv模块,提供对 flv 视频的伪流支持
--with-http_ssl_module #启用 SSL模块,提供SSL加密功能
--with-stream #启用 stream模块,提供4层调度
----------------------------------------------------------------------------------------------------------
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-stream --with-http_ssl_module
make && make install
# 创建系统服务
vim /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecrReload=/bin/kill -s HUP $MAINPID
ExecrStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
chmod 754 /lib/systemd/system/nginx.service
# 添加服务配置内容
systemctl start nginx
systemctl enable nginx

4.3 Tomcat 应用服务器部署
bash
systemctl stop firewalld
setenforce 0
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile
export JAVA_HOME=/usr/local1/jdk1.8.0_91
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source /etc/profile
==============================================================
tar zxvf apache-tomcat-8.5.35.tar.gz
mv /opt/apache-tomcat-8.5.35/ /usr/local/tomcat
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
netstat -ntap | grep 8080
第二台直接拷贝即可
cp -r /usr/local/tomcat /usr/local/tomcat1

4.4 动静分离配置
4.4.1 Tomcat1 配置
bash
cd /usr/local/tomcat/webapps/ROOT/
mv index.jsp index.jsp.bak # 备份默认的index.jsp
vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title> #指定为 test1 页面
</head>
<body>
<% out.println("动态页面 1,http://www.test1.com");%>
</body>
</html>
# 重启Tomcat
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh

4.4.2 Tomcat2 配置
bash
cd /usr/local/tomcat1/webapps/ROOT/
mv index.jsp index.jsp.bak # 备份默认的index.jsp
vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test2 page</title> #指定为 test2 页面
</head>
<body>
<% out.println("动态页面 2,http://www.test2.com");%>
</body>
</html>
# 修改server.xml
vim /usr/local/tomcat/tomcat1/conf/server.xml
22 <Server port="8006" shutdown="SHUTDOWN"> # 8005 换成8006
69 <Connector port="8081" protocol="HTTP/1.1" # 8080 改成8081
116 <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" /> # 把8009 改成8010
# 重启Tomcat
/usr/local/tomcat/tomcat1/bin/shutdown.sh
/usr/local/tomcat/tomcat1/bin/startup.sh

4.4.3 Nginx 配置
bash
#准备静态页面和静态图片
echo '<html><body><h1>这是静态页面</h1></body></html>' > /usr/local/nginx/html/index.html
cp /root/game.jpg /usr/local/nginx/html/img

bash
# 修改nginx配置文件
vim /usr/local/nginx/conf/nginx.conf
......
http {
......
#gzip on;
#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大
upstream tomcat_server {
server 192.168.10.123:8080 weight=1;
server 192.168.10.123:8081 weight=1;
}
server {
listen 80;
server_name www.yjs.com;
charset utf-8;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#配置Nginx处理动态页面请求,将 .jsp文件请求转发到Tomcat 服务器处理
location ~ .*\.jsp$ {
proxy_pass http://tomcat_server;
#设置后端的Web服务器可以获取远程客户端的真实IP
##设定后端的Web服务器接收到的请求访问的主机名(域名或IP、端口),默认HOST的值为proxy_pass指令设置的主机名。如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。
proxy_set_header HOST $host;
##把$remote_addr赋值给X-Real-IP,来获取源IP
proxy_set_header X-Real-IP $remote_addr;
##在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#配置Nginx处理静态图片请求
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/img;
# 缓存 10 天
expires 10d;
}
......
}
......
}
# 加载配置文件
systemctl reload nginx
4.5 效果测试
1、测试静态页面效果
- 静态页面访问:
http://192.168.10.110/

- 浏览器访问静态图片 http://192.168.10.110/game.jpg

2、动态页面负载均衡测试:不断刷新 http://192.168.10.110/index.jsp
因为负载均衡策略选择轮询 的方式,所以动态请求会轮流 转发给Tomcat1和Tomcat2。
总结
本文全面介绍了Nginx反向代理与负载均衡的配置实践,以及Tomcat应用服务器的部署与集成方案。主要内容包括:
- Nginx反向代理:工作原理、基础配置方法
- 负载均衡策略:详细解析6种主流算法及适用场景
- Tomcat核心知识:架构原理、关键配置、数据源集成
- 实战部署方案:完整的Nginx+Tomcat负载均衡环境搭建
- 动静分离实现:智能区分处理动态请求和静态资源
通过本指南,您可以构建出高性能、高可用的Web服务架构,有效应对高并发场景,提升系统稳定性和可扩展性。实际生产环境中,建议根据具体业务需求选择合适的负载均衡策略,并配合健康检查机制确保服务可靠性。