Nginx反向代理和负载均衡详解及使用Nginx和tomcat共同实现动静分离配置
文章目录
- 前言
- 一、Nginx的反向代理
- 1.1 原理
- 1.2 实验配置
- 二、Nginx的负载均衡
- 2.1 基本原理
- 2.2 常见负载均衡策略
- 2.2.1 轮询(Round Robin)
- 2.2.2 最少连接数(Least Connections)
- 2.2.3 IP哈希(IP Hash)
- 2.2.4 加权轮询(Weighted Round Robin)
- 2.2.5 最少时间算法(Least Time)
- 2.2.6 一致性哈希(Consistent Hashing)
- 2.3 配置示例
- 2.3.1 基础轮询配置
- 2.3.2 带权重与故障转移配置
- 2.4 高可用与健康检查
- 三、Tomcat后端服务器
- 3.1 Tomcat的本质
- 3.2 运行原理
- 3.3 主要配置文件
- 3.4 应用接口调用
- 3.5 数据库接口调用
- 3.6 部署Tomcat
- 3.6.1 环境准备
- 3.6.2 JDK配置
- 3.6.3 安装与启动Tomcat
- 四、Nginx+Tomcat动静分离与负载均衡实践
- 4.1 环境规划
- 4.2 Nginx服务器的部署
- 4.3 两台Tomcat服务器的部署
- 4.4 动静分离配置
- 4.4.1 Tomcat1配置
- 4.4.2 Tomcat2配置
- 4.4.3 Nginx配置
- 4.5 测试验证
- 总结
前言
在现代Web服务架构中,Nginx作为高性能的反向代理与负载均衡服务器,与Tomcat等Java应用服务器的配合使用,已成为构建高可用、高并发系统的常见方案。本文将从原理到实践,系统介绍Nginx的反向代理、负载均衡策略,以及Tomcat的基本原理与部署,并通过一个完整的实验演示如何搭建Nginx+Tomcat动静分离与负载均衡环境。
一、Nginx的反向代理
1.1 原理
反向代理是指用户请求首先到达Nginx服务器,再由Nginx将请求转发给后端的应用服务器(如Tomcat、Node.js、Spring Boot等)。Nginx在此过程中充当“中转站”的角色,客户端并不知道真正提供服务的是哪台后端服务器。
图示:
1.2 实验配置
编辑Nginx配置文件 nginx.conf
,在 server
块中添加如下配置:
server {listen 80;server_name localhost;location / {proxy_pass http://127.0.0.1:8080; # 将请求转发到后端8080端口proxy_set_header Host $host; # 保留原始Host头proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}
保存配置后,执行以下命令重新加载Nginx:
nginx -s reload
此时访问 http://localhost/
的请求将被Nginx转发至 http://127.0.0.1:8080/
。
二、Nginx的负载均衡
2.1 基本原理
Nginx作为反向代理服务器,接收客户端请求后,根据预设的负载均衡策略将请求分发到多台后端服务器(upstream server),从而提高系统的并发处理能力、可用性和扩展性。
优势包括:
- 提高性能:分担单台服务器压力;
- 高可用性:某台服务器故障时自动转发至其他节点;
- 可扩展性:支持动态添加或移除后端节点。
2.2 常见负载均衡策略
2.2.1 轮询(Round Robin)
默认策略,按顺序将请求依次分配给每台后端服务器。
配置示例:
upstream backend {server backend1.example.com;server backend2.example.com;server backend3.example.com;
}
2.2.2 最少连接数(Least Connections)
将请求分配给当前活动连接数最少的服务器。
配置示例:
upstream backend {least_conn;server backend1.example.com;server backend2.example.com;server backend3.example.com;
}
2.2.3 IP哈希(IP Hash)
根据客户端IP的哈希值将请求固定分配给某一台服务器,适用于需要会话保持的场景。
配置示例:
upstream backend {ip_hash;server backend1.example.com;server backend2.example.com;server backend3.example.com;
}
2.2.4 加权轮询(Weighted Round Robin)
根据服务器权重分配请求,权重越高接收的请求越多。
配置示例:
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及以上版本)。
配置示例:
upstream backend {least_time header;server backend1.example.com;server backend2.example.com;server backend3.example.com;
}
2.2.6 一致性哈希(Consistent Hashing)
根据请求的特定参数(如URL)进行哈希计算,确保服务器变动时仅部分请求需要重新分配。
配置示例:
upstream backend {hash $request_uri consistent;server backend1.example.com;server backend2.example.com;server backend3.example.com;
}
2.3 配置示例
2.3.1 基础轮询配置
http {upstream backend {server 192.168.0.101;server 192.168.0.102;}server {listen 80;location / {proxy_pass http://backend;}}
}
2.3.2 带权重与故障转移配置
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
三、Tomcat后端服务器
3.1 Tomcat的本质
Tomcat是一个Servlet容器,也可作为轻量级Web应用服务器(Web Server + Servlet Container),主要职责包括:
- 接收HTTP请求;
- 将请求分发给对应的Web应用;
- 执行Servlet/JSP并生成响应;
- 返回HTTP响应给客户端。
3.2 运行原理
- 启动阶段:加载配置,初始化Connector、Service、Engine等组件;
- 接收请求:Connector监听HTTP请求,封装为Request对象;
- 请求分发:Mapper根据URL找到对应的Context与Wrapper(Servlet);
- 执行Servlet:调用Servlet的
service()
方法处理请求; - 响应返回:将Response转换为HTTP响应报文返回客户端。
3.3 主要配置文件
配置文件 | 作用描述 |
---|---|
conf/server.xml | 主配置,定义Connector、Engine、Host等 |
conf/web.xml | 全局Web应用默认配置 |
context.xml | Web应用级别配置,如数据源、Session |
tomcat-users.xml | 用户与角色管理配置 |
WEB-INF/web.xml | 单个Web应用的Servlet、Filter等配置 |
3.4 应用接口调用
Tomcat在启动时加载应用的web.xml
或注解(如@WebServlet
),将请求参数封装为HttpServletRequest
,调用对应的Servlet或框架(如Spring MVC),最后将业务处理结果通过HttpServletResponse
返回。
3.5 数据库接口调用
通过JNDI数据源实现数据库连接池管理:
-
配置数据源(在
context.xml
中):<Resource name="jdbc/MyDB" auth="Container"type="javax.sql.DataSource"maxActive="20"username="root"password="123456"driverClassName="com.mysql.cj.jdbc.Driver"url="jdbc:mysql://localhost:3306/test"/>
-
代码调用:
Context initCtx = new InitialContext(); DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/MyDB"); Connection conn = ds.getConnection();
3.6 部署Tomcat
3.6.1 环境准备
systemctl stop firewalld
setenforce 0
3.6.2 JDK配置
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile
# 添加以下内容:
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:$PATHsource /etc/profile
3.6.3 安装与启动Tomcat
tar zxvf apache-tomcat-8.5.16.tar.gz
mv apache-tomcat-8.5.16 /usr/local/tomcat
/usr/local/tomcat/bin/startup.sh
netstat -ntap | grep 8080
四、Nginx+Tomcat动静分离与负载均衡实践
4.1 环境规划
- Nginx服务器:192.168.10.123:80
- Tomcat服务器1:192.168.10.120:8080
- Tomcat服务器2:192.168.10.120:8081
4.2 Nginx服务器的部署
systemctl stop firewalld
setenforce 0yum -y install pcre-cdevel zlib-devel openssl-devel gc gcc-c++ makeuseradd -M -s /sbin/nologin nginxcd /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_modulemake -j2 && make installln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/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.targetchmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service
4.3 两台Tomcat服务器的部署
systemctl stop firewalld
setenforce 0tar 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:$PATHsource /etc/profile 使用java -version查看是否有
===========================================
tar zxvf apache-tomcat-8.5.16.tar.gzmv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.shnetstat -ntap | grep 8080第二台直接拷贝即可
cp -r /usr/local/tomcat /usr/local/tomcat1
4.4 动静分离配置
4.4.1 Tomcat1配置
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title>
</head>
<body>
<% out.println("动态页面 1,http://www.test1.com");%>
</body>
</html>
4.4.2 Tomcat2配置
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test2 page</title>
</head>
<body>
<% out.println("动态页面 2,http://www.test2.com");%>
</body>
</html>
4.4.3 Nginx配置
upstream tomcat_server {server 192.168.10.23:8080 weight=1;server 192.168.10.22:8080 weight=1;server 192.168.10.22:8081 weight=1;
}server {listen 80;server_name www.kgc.com;location ~ .*\.jsp$ {proxy_pass http://tomcat_server;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 ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {root /usr/local/nginx/html/img;expires 10d;}location / {root html;index index.html index.htm;}
}
4.5 测试验证
- 静态页面访问:
http://192.168.10.22/
- 静态图片访问:
http://192.168.10.22/game.jpg
- 动态请求负载均衡:不断刷新
http://192.168.10.22/index.jsp
总结
本文系统介绍了Nginx的反向代理与负载均衡原理,详细讲解了多种负载均衡策略及其配置方式,并深入剖析了Tomcat作为Java应用服务器的运行机制与配置管理。最后通过一个完整的实验演示了如何搭建Nginx+Tomcat动静分离与负载均衡集群,验证了Nginx在高并发场景下的优秀表现和Tomcat的稳定运行能力。这一架构不仅提升了系统的并发处理能力,也显著增强了服务的可用性与可扩展性,是现代Web系统中不可或缺的技术组合。