Nginx 正向代理、反向代理与负载均衡实战(Docker + Tomcat 版)

52 阅读4分钟

一、核心概念解析

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";
}

五、总结

  • 正向代理:替客户端“跑腿”,客户端知道目标地址。
  • 反向代理:替服务端“接待”,客户端不知道后端地址。
  • 负载均衡:反向代理的进阶玩法,实现请求分流,提升系统稳定性。