反向代理与负载均衡

1、反向代理

1.1 原理

用户请求先到 Nginx,再由 Nginx 把请求转发给后端的应用服务器(比如 Tomcat、Node.js、Spring Boot)

1.2 配置

## 编辑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;   # 获取客户端真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

## 保存配置后执行
nginx -s reload

2、负载均衡

2.1 原理

Nginx 作为反向代理服务器,接收来自客户端的请求,然后根据配置的负载均衡策略,将请求转发到后端的多个应用服务器(upstream server)

好处:

  • 提高性能:分担单台服务器压力
  • 高可用性:某台服务器宕机,Nginx 自动转发到其他正常的节点
  • 可扩展性:轻松添加或移除后端节点

2.2 常见负载均衡策略

2.2.1 轮询

轮询算法是 Nginx 的默认分流算法。它按顺序将请求依次分配给每一台后端服务器,直到最后一台服务器,然后重新从第一台服务器开始。这种方法简单且均匀地分配了流量。

数据流向:每个请求依次被分配到下一个服务器。假设有三台服务器(Server A、Server B、Server C),第一个请求被分配到 Server A,第二个请求分配到 Server B,第三个请求分配到 Server C,第四个请求又回到 Server A,依此类推。
特点:请求均匀分布,无视服务器的当前负载和响应时间

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
}

2.2.2 最少连接数

最少连接数算法将请求分配给当前活动连接数最少的服务器。这种算法适用于请求处理时间不均匀的情况,可以有效平衡服务器的负载。

数据流向:每个请求被分配到当前连接数最少的服务器。例如,Server A 有 2 个连接,Server B 有 5 个连接,新的请求会被分配到 Server A。
特点:动态均衡负载,适用于请求处理时间不一的场景

upstream backend {
       least_conn;
       server backend1.example.com;
       server backend2.example.com;
       server backend3.example.com;
   }

2.2.3 加权轮询

加权轮询算法允许为每台服务器设置权重,权重越大的服务器将会获得更多的请求。适用于服务器性能不均衡的情况。

数据流向:根据服务器设置的权重值分配请求。假设 Server A 权重为 3,Server B 权重为 1,则 4 个请求中,3 个会被分配到 Server A,1 个会被分配到 Server B。
特点:高权重服务器接收更多的请求,适用于服务器性能差异较大的场景。

upstream backend {
    server backend1.example.com weight=3;
    server backend2.example.com weight=1;
    server backend3.example.com weight=2;
}

2.2.4 最少时间算法

最少时间算法基于请求的响应时间,将请求分配给响应时间最短的服务器。这种算法在 Nginx 1.15.3 及以后版本中可用,适用于需要最大化响应速度的场景。

数据流向:每个请求分配到响应时间最短或平均连接时间最短的服务器。假设 Server A 的响应时间较快,Server B 较慢,则新的请求更可能流向 Server A。
特点:进一步优化了最少连接算法,适用于高负载环境下的动态负载均衡。

   upstream backend {
       least_time header;
       server backend1.example.com;
       server backend2.example.com;
       server backend3.example.com;
   }

2.2.5 IP 哈希

IP 哈希算法通过计算客户端 IP 地址的哈希值,将请求始终分配给同一台服务器。适用于需要将特定客户端的请求固定在同一台服务器上的场景。

数据流向:每个客户端的 IP 地址被哈希计算,然后根据哈希值将请求固定分配到某一台服务器。假设客户端 X 的哈希值指向 Server A,客户端 Y 的哈希值指向 Server B,则无论多少次请求,X 的请求总是流向 Server A,Y 的请求总是流向 Server B。
特点:同一个客户端总是被分配到同一台服务器,有助于会话保持。

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
}

2.3 带权重和故障转移

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
    server backup1.example.com  backup;
}
  • weight=5 表示权重
  • max_fails=3 表示最大失败次数
  • fail_timeout=30s 表示尝试最大失败次数之后需要等待30秒后接着重试
  • backup 表示备用服务器,一旦其他服务器挂了就会启用备用服务器

3、tomcat

3.1 概述

Tomcat 本质上是一个 Servlet 容器,也可以称作一个轻量级 Web 应用服务器

  • 接收 HTTP 请求(内置了一个简单的 HTTP 服务器)
  • 将请求分发给对应的 Web 应用(基于 URL 映射)
  • 执行 Servlet / JSP 并生成响应
  • 返回 HTTP 响应给客户端

3.2 运行原理

  1. 启动
    • 加载 server.xml 配置,启动各个 Connector(监听端口,如 8080)
    • 初始化 ServiceEngineHostContext 组件
    • 创建并初始化 Servlet 容器
  2. 接收请求
    • Connector 监听 HTTP 请求(基于 NIO/线程池)
    • 请求被封装为 Request 对象
  3. 请求分发
    • Mapper 根据 URL → 找到对应的 Context(即某个 Web 应用)
    • 找到对应的 Wrapper(某个 Servlet)
  4. 执行 Servlet
    • Tomcat 调用 Servlet 的 service() 方法
    • Servlet 处理请求,可能访问数据库或调用其他 API
    • 返回 Response 对象
  5. 响应客户端
    • Tomcat 将 Response 转换为 HTTP 响应报文
    • 通过 Socket 返回给客户端浏览器

3.3 主要配置文件

server.xml
Tomcat 的主配置文件,定义 Connector(端口、协议)、Engine、Host、Context 等
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

## 关闭防火墙和增强功能
systemctl stop firewalld
setenforce 0

## 解压jdk包
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/

## 配置java环境
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

## 解压tomcat安装包
tar zxvf apache-tomcat-8.5.16.tar.gz

## 修改服务名
mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat

## 启动tomcat
/usr/local/tomcat/bin/shutdown.sh 
/usr/local/tomcat/bin/startup.sh

## 查看
netstat -ntap | grep 8080

4、部署反向代理与负载均衡

4.1 部署Nginx

systemctl stop firewalld
setenforce 0

yum -y install pcre-cdevel zlib-devel openssl-devel gc 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

ln -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.target

chmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service

4.2 部署tomcat

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.16.tar.gz

mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat

/usr/local/tomcat/bin/shutdown.sh 
/usr/local/tomcat/bin/startup.sh

netstat -ntap | grep 8080

4.3 tomcat配置

mkdir /usr/local/tomcat/webapps/test
vim /usr/local/tomcat/webapps/test/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>


vim /usr/local/tomcat/conf/server.xml
#由于主机名 name 配置都为 localhost,需要删除前面的 HOST 配置
<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>

/usr/local/tomcat/bin/shutdown.sh 
/usr/local/tomcat/bin/startup.sh 

4.4 nginx 配置

## 准备静态页面和静态图片
echo '<html><body><h1>这是静态页面</h1></body></html>' > /usr/local/nginx/html/index.html

mkdir /usr/local/nginx/html/img

cp /root/game.jpg /usr/local/nginx/html/img​

## 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf

    upstream tomcat_server {
	server 192.168.100.99:8080;
	server 192.168.100.135:8080;
    }
    server {
	listen 80;
	server_name localhost;
	charset utf-8;
	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 / {
		root /usr/local/nginx/html;
		index index.html index.htm;
	}
	location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
		root /usr/local/nginx/html/img;
		expires 10d;
	}
	error_page   500 502 503 504  /50x.html;
	location = /50x.html {
		root   html;
	}
    }

测试

测试静态页面效果
浏览器访问 http://192.168.100.56/
浏览器访问 http://192.168.100.56/cartoon.jpg

测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.10.56/index.jsp

总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值