基于Nginx实现反向代理、负载均衡与动静分离完整部署指南

基于Nginx实现反向代理、负载均衡与动静分离完整部署指南

文章目录

在实际生产环境中,单台应用服务器往往难以承受高并发请求的压力,同时静态资源与动态资源混合处理也会降低服务响应效率。Nginx作为一款高性能的HTTP和反向代理服务器,凭借其轻量级、高并发的特性,成为实现负载均衡与动静分离的理想选择。本文将详细介绍如何基于Nginx部署反向代理、负载均衡,并结合Tomcat实现动静分离,构建高效稳定的Web服务架构。

一、架构规划与环境准备

1.1 架构设计思路

本次部署采用"Nginx前端负载均衡+Tomcat后端应用"的架构模式,核心目标如下:

  • 反向代理:通过Nginx接收客户端请求,隐藏后端Tomcat服务器的真实地址,提高服务安全性。
  • 负载均衡:将客户端的动态请求分发到多台Tomcat服务器,避免单台服务器过载,提升服务并发能力。
  • 动静分离:Nginx直接处理静态资源(图片、HTML等),动态请求(JSP等)转发至Tomcat处理,优化资源处理效率。

1.2 服务器规划

服务器角色 IP地址 端口 主要作用
Nginx负载均衡器 192.168.10.22 80 反向代理、负载均衡、静态资源处理
Tomcat应用服务器1 192.168.10.17 8080 处理动态请求(JSP)
Tomcat应用服务器2 192.168.10.17 8081 处理动态请求(JSP)

1.3 环境依赖

  • 操作系统:CentOS 7(所有服务器均需安装)

  • 软件版本:Nginx 1.20.2、JDK 1.8、Tomcat 8.5.16

  • 前置操作:所有服务器关闭防火墙、禁用SELinux,避免端口拦截。

    bash 复制代码
    # 关闭防火墙
    systemctl stop firewalld
    systemctl disable firewalld
    # 禁用SELinux
    setenforce 0
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

二、部署Nginx负载均衡器

Nginx是整个架构的入口,需先完成其安装与基础配置,确保能够正常接收和转发请求。

2.1 安装Nginx依赖包

Nginx编译安装需依赖pcre、zlib等库,通过yum安装相关开发包:

bash 复制代码
yum -y install pcre-cdevel zlib-devel openssl-devel gc gcc-c++ make

2.2 创建Nginx专用用户

为提高安全性,创建无登录权限的nginx用户用于运行Nginx服务:

bash 复制代码
useradd -M -s /sbin/nologin nginx

2.3 编译安装Nginx

  1. 上传Nginx 1.20.2安装包至/opt目录,解压后进入源码目录:

    bash 复制代码
    cd /opt
    tar zxvf nginx-1.20.2.tar.gz
    cd nginx-1.20.2/
  2. 配置编译参数(启用SSL、stream、状态统计等核心模块):

bash 复制代码
./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-http_ssl_module \
--with-stream
  1. 编译并安装:

    bash 复制代码
    make && make install
  2. 创建软链接,方便全局调用nginx命令:

    bash 复制代码
    ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

2.4 配置Nginx系统服务

为便于通过systemctl管理Nginx,创建系统服务文件:

bash 复制代码
vim /lib/systemd/system/nginx.service

添加如下内容:

ini 复制代码
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.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 start nginx.service
systemctl enable nginx.service
# 验证启动状态
systemctl status nginx.service

三、部署后端Tomcat应用服务器

Tomcat作为Java Web容器,负责处理动态JSP请求。本次在同一台服务器上部署2个Tomcat实例(端口8080、8081),模拟多台应用服务器。

3.1 安装JDK(Tomcat依赖)

  1. 上传JDK 1.8安装包至/opt目录,解压至/usr/local

    bash 复制代码
    tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
  2. 配置JDK环境变量:

    bash 复制代码
    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
  3. 生效环境变量:

    bash 复制代码
    source /etc/profile
    # 验证JDK安装
    java -version

3.2 部署Tomcat 8080实例

  1. 上传Tomcat 8.5.16安装包至/opt目录,解压并重命名:

    bash 复制代码
    tar zxvf apache-tomcat-8.5.16.tar.gz
    mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat
  2. 创建测试动态页面:

    bash 复制代码
    mkdir /usr/local/tomcat/webapps/test
    vim /usr/local/tomcat/webapps/test/index.jsp

    添加如下JSP内容(标记为test1页面,便于区分负载均衡效果):

    jsp 复制代码
    <%@ 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>
  3. 配置Tomcat虚拟主机:

    bash 复制代码
    vim /usr/local/tomcat/conf/server.xml

    删除原有<Host>配置,添加如下内容(指定应用路径):

    xml 复制代码
    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
        <Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true">
        </Context>
    </Host>
  4. 启动Tomcat并验证:

    bash 复制代码
    # 启动Tomcat
    /usr/local/tomcat/bin/startup.sh
    # 验证8080端口是否监听
    netstat -ntap | grep 8080

3.3 部署Tomcat 8081实例

通过复制8080实例快速创建8081实例,只需修改端口和测试页面即可:

  1. 复制Tomcat目录并命名为tomcat1:

    bash 复制代码
    cp -r /usr/local/tomcat /usr/local/tomcat1
  2. 修改Tomcat1端口(避免端口冲突):

    bash 复制代码
    vim /usr/local/tomcat1/conf/server.xml

    需修改3处端口:

    • 关闭端口:<Server port="8005" shutdown="SHUTDOWN"> → 改为8006
    • 监听端口:<Connector port="8080" protocol="HTTP/1.1"> → 改为8081
    • AJP端口:<Connector port="8009" protocol="AJP/1.3"> → 改为8010
  3. 修改测试页面(标记为test2):

    bash 复制代码
    vim /usr/local/tomcat1/webapps/test/index.jsp

    修改内容如下:

    jsp 复制代码
    <%@ 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. 启动Tomcat1并验证:

    bash 复制代码
    /usr/local/tomcat1/bin/startup.sh
    netstat -ntap | grep 8081

四、配置Nginx反向代理、负载均衡与动静分离

Nginx的核心配置集中在nginx.conf文件中,需在此文件中实现负载均衡池定义、动静请求分发规则。

4.1 准备静态资源

在Nginx服务器上创建静态页面和图片目录,用于测试动静分离:

bash 复制代码
# 创建静态首页
echo '<html><body><h1>这是Nginx处理的静态页面</h1></body></html>' > /usr/local/nginx/html/index.html
# 创建图片目录并上传测试图片(此处以上传game.jpg为例)
mkdir /usr/local/nginx/html/img
cp /root/game.jpg /usr/local/nginx/html/img

4.2 修改Nginx核心配置

编辑nginx.conf文件:

bash 复制代码
vim /usr/local/nginx/conf/nginx.conf

重点修改http块内容,添加负载均衡池、动静分离规则,完整配置如下:

nginx 复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 1. 定义负载均衡池(tomcat_server),weight为权重(权重越高,被分配概率越大)
    upstream tomcat_server {
        server 192.168.10.17:8080 weight=1;  # Tomcat 8080
        server 192.168.10.17:8081 weight=1;  # Tomcat 8081
    }

    # 2. 配置虚拟主机
    server {
        listen       80;
        server_name  www.test.com;  # 可自定义域名,需在本地hosts解析

        charset utf-8;
        access_log  logs/host.access.log  main;

        # 3. 动态请求转发(.jsp结尾请求转发至负载均衡池)
        location ~ .*\.jsp$ {
            proxy_pass http://tomcat_server;  # 转发至定义的负载均衡池
            # 传递客户端真实IP和主机名给后端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;
        }

        # 4. 静态资源处理(图片、CSS等由Nginx直接返回)
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
            root /usr/local/nginx/html/img;  # 静态资源根目录
            expires 10d;  # 设置浏览器缓存10天,减少重复请求
        }

        # 5. 默认请求处理(静态首页)
        location / {
            root   html;
            index  index.html index.htm;
        }

        # 错误页面配置
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

4.3 验证Nginx配置并重启

bash 复制代码
# 检查配置文件语法是否正确
nginx -t
# 重启Nginx使配置生效
systemctl reload nginx.service

五、功能测试

配置完成后,通过浏览器访问Nginx服务器IP(192.168.10.22),分别测试静态资源、动态请求、负载均衡效果。

5.1 静态资源测试

  1. 访问静态首页:http://192.168.10.22
    预期结果:显示"这是Nginx处理的静态页面",说明Nginx正常处理静态HTML。
  2. 访问静态图片:http://192.168.10.22/game.jpg
    预期结果:成功显示上传的game.jpg图片,说明静态图片处理正常。

5.2 负载均衡与动态请求测试

访问动态JSP页面:http://192.168.10.22/index.jsp
预期结果

  • 首次刷新可能显示"动态页面 1,http://www.test1.com"(Tomcat 8080处理);
  • 再次刷新可能显示"动态页面 2,http://www.test2.com"(Tomcat 8081处理);
  • 多次刷新后,页面在两个动态页面间交替显示,说明负载均衡生效,请求被均匀分发到两台Tomcat服务器。

六、常见问题与解决方案

  1. Tomcat启动失败,端口被占用?
    执行netstat -ntap | grep 8080查看占用端口的进程,杀死对应进程或修改Tomcat端口。
  2. 访问JSP页面返回404?
    检查Tomcat的server.xml<Context>docBase路径是否正确,确保index.jsp存在于该路径下。
  3. Nginx配置后无法转发请求?
    确认Nginx的upstream中Tomcat的IP和端口是否正确,同时检查Tomcat是否启动、防火墙是否关闭。

七、总结

本文通过"Nginx+Tomcat"架构实现了反向代理、负载均衡与动静分离,核心优势如下:

  • 高并发支持:Nginx处理静态资源效率远高于Tomcat,动静分离减少了Tomcat的资源消耗;
  • 负载均衡:通过权重分配请求,避免单台Tomcat过载,提升服务可用性;
  • 安全性提升:客户端仅与Nginx交互,后端Tomcat不直接暴露在公网,降低攻击风险。

该架构可根据实际业务需求扩展Tomcat服务器数量,进一步提升并发处理能力,适用于中小规模Web应用的生产环境部署。

相关推荐
荣--1 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森1 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜2 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB3 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode4 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220705 天前
如何搭建本地yum源(上)
运维
ping某6 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树888 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠8 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质8 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务