一、核心概念解析
1. 正向代理
- 作用对象:客户端
- 核心逻辑:代理客户端发起请求。客户端明确知道目标服务器地址,但因网络限制(如跨网、权限)无法直接访问,需通过正向代理服务器转发请求。
- 典型场景:翻墙工具、企业内网代理访问外网、校园网代理访问资源。
2. 反向代理
- 作用对象:服务端
- 核心逻辑:代理服务端接收请求。客户端不知道具体的后端服务器地址,只需访问反向代理服务器,由反向代理将请求转发给后端服务器,并将结果返回给客户端。
- 典型场景:隐藏后端服务 IP、统一服务入口、SSL 证书卸载、动静分离。
3. 负载均衡
- 核心逻辑:基于反向代理,将客户端请求均匀分发到多个后端服务器,避免单台服务器过载,提升系统可用性和并发能力。
- 典型场景:多实例 Tomcat 部署、微服务集群、高并发业务场景。
二、实战准备:Docker 部署多实例 Tomcat
官方 Tomcat 镜像的默认页面存放在
webapps.dist目录,需移动到webapps目录才能正常访问,我们通过 Dockerfile 一键构建镜像。
1. 编写 Dockerfile
# 基础镜像:官方最新版 Tomcat
FROM tomcat:latest
# 设置工作目录
WORKDIR /usr/local/tomcat/webapps
# 移动默认页面到 webapps 目录,确保启动后可访问 Tomcat 欢迎页
RUN mv /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/
# 暴露 Tomcat 默认端口 8080
EXPOSE 8080
# 容器启动命令:启动 Tomcat
CMD ["catalina.sh", "run"]
2. 构建镜像并启动多实例 Tomcat
# 1. 构建 Tomcat 镜像,标签为 tomcat8080:v1
[root@master tomcat]# docker build -t tomcat8080:v1 .
# 2. 启动第一个 Tomcat 实例,主机端口 8080 映射容器端口 8080
[root@master tomcat]# docker run -d --name tomcat8080 -p 8080:8080 tomcat8080:v1
# 3. 启动第二个 Tomcat 实例,主机端口 8081 映射容器端口 8080
[root@master tomcat]# docker run -d --name tomcat8081 -p 8081:8080 tomcat8080:v1
# 4. 查看容器运行状态
[root@master tomcat]# docker ps | grep tomcat
052a3dadac9c tomcat8080:v1 "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:8081->8080/tcp tomcat8081
b2546016f9e4 tomcat8080:v1 "catalina.sh run" 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp tomcat8080
3. 验证 Tomcat 实例
分别访问以下地址,能看到 Tomcat 默认欢迎页则说明部署成功:
- Tomcat 实例 1:
http://服务器IP:8080 - Tomcat 实例 2:
http://服务器IP:8081
三、配置 Nginx 反向代理 + 负载均衡
前提:已安装 Nginx,若未安装可参考 Nginx 官方安装指南
1. Nginx 核心配置文件(nginx.conf)
worker_processes 1; # 工作进程数,建议设置为 CPU 核心数
#pid logs/nginx.pid; # PID 文件路径,可根据需要开启
events {
worker_connections 1024; # 每个工作进程的最大并发连接数
}
http {
# 定义负载均衡集群,集群名称自定义为 tomcat
upstream tomcat {
server 192.168.200.10:8080; # 第一个 Tomcat 实例地址 + 端口
server 192.168.200.10:8081; # 第二个 Tomcat 实例地址 + 端口
# 可选:加权轮询配置 weight=数值,数值越大优先级越高
# server 192.168.200.10:8080 weight=3;
# server 192.168.200.10:8081 weight=1;
# 可选:ip_hash 实现会话保持,解决用户登录态丢失问题
# ip_hash;
}
include mime.types; # 引入 MIME 类型映射文件
default_type application/octet-stream; # 默认响应类型
sendfile on; # 开启高效文件传输模式
keepalive_timeout 65; # 长连接超时时间
server {
listen 80; # Nginx 监听端口
server_name localhost; # 服务域名,可改为实际域名如 example.com
location / {
# 反向代理核心配置:将请求转发到 upstream 定义的 tomcat 集群
proxy_pass http://tomcat;
# 关键补充:传递客户端真实 IP 和 Host 头,后端服务可获取真实请求信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 配置 5xx 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html; # 错误页面所在目录
}
}
}
2. 重载 Nginx 配置并验证
# 1. 检查配置文件语法是否正确(关键步骤,避免配置错误导致 Nginx 启动失败)
[root@master conf]# nginx -t
# 2. 平滑重载配置,无需重启 Nginx 服务
[root@master conf]# nginx -s reload
3. 验证负载均衡效果
访问 http://服务器IP(Nginx 监听的 80 端口),反复刷新页面:
- Nginx 默认使用 轮询算法,请求会依次分发到 8080 和 8081 两个 Tomcat 实例。
- 若配置了
ip_hash,同一客户端的请求会始终分发到同一台 Tomcat 实例,实现会话保持。
四、进阶优化建议
1. 负载均衡算法选型
| 算法 | 配置语法 | 适用场景 |
|---|---|---|
| 轮询(默认) | server IP:PORT; | 后端服务器性能一致 |
| 加权轮询 | server IP:PORT weight=3; | 后端服务器性能差异较大 |
| IP 哈希 | ip_hash; | 需要会话保持的业务(如登录态) |
| 最少连接 | least_conn; | 后端服务器连接数不均的场景 |
2. 后端服务健康检查
Nginx 默认无主动健康检查功能,可通过 proxy_next_upstream 配置故障转移,自动跳过故障节点:
location / {
proxy_pass http://tomcat;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
3. 静态资源缓存优化
对 Tomcat 中的 JS、CSS、图片等静态资源,在 Nginx 配置缓存规则,减少后端压力:
location ~* .(js|css|png|jpg|gif)$ {
proxy_pass http://tomcat;
expires 7d; # 缓存有效期 7 天
add_header Cache-Control "public, max-age=604800";
}
五、总结
- 正向代理:替客户端“跑腿”,客户端知道目标地址。
- 反向代理:替服务端“接待”,客户端不知道后端地址。
- 负载均衡:反向代理的进阶玩法,实现请求分流,提升系统稳定性。