Nginx代理负载均衡
课程目标
-
正向代理与反向代理
-
nginx反向代理
-
动静分离
-
负载均衡
-
nginx负载均衡
课程实验
-
正向代理与反向代理讲解
-
nginx反向代理配置
-
nginx-tomcat实现动静分离部署
-
负载均衡概述及负载策略
-
nginx-tomcat实现负载均衡
课堂引入
- 生活中我们经常会接触到很多的中介,房产中介等,中介的存在使我们的相关业务办理变得更加方便。那么,代理本质上就是起到中介的效果。
授课进程
一、正向代理与反向代理
1、概述
在计算机网络领域,代理服务器扮演着至关重要的角色,它在服务器与客户端之间充当中间人的角色,有效地提高系统的安全性、性能和可扩展性

2、正向代理
客户端想要访问一个服务器,但是它可能无法直接访问这台服务器,这时候这可找一台可以访问目标服务器的另外一台服务器,而这台服务器就被当做是代理人的角色 ,称之为代理服务器,于是客户端把请求发给代理服务器,由代理服务器获得目标服务器的数据并返回给客户端。客户端是清楚目标服务器的地址的,而目标服务器是不清楚来自客户端,它只知道来自哪个代理服务器,所以正向代理可以屏蔽或隐藏客户端的信息。

3、反向代理
从上面的正向代理,你会大概知道代理服务器是为客户端作代理人,它是站在客户端这边的。其实反向代理就是代理服务器为服务器作代理人,站在服务器这边,它就是对外屏蔽了服务器的信息,常用的场景就是多台服务器分布式部署,像一些大的网站,由于访问人数很多,就需要多台服务器来解决人数多的问题,这时这些服务器就由一个反向代理服务器来代理,客户端发来请求,先由反向代理服务器,然后按一定的规则分发到明确的服务器,而客户端不知道是哪台服务器。常常用nginx来作反向代理

二、nginx代理配置
1、概述及原理
作为反向代理服务器,Nginx 可以帮助提高网站的响应速度和可用性,同时隐藏后端服务器的复杂性,这使得 Nginx 在负载均衡和缓存方面非常有用

比如我之前在部署PHP项目的时候,nginx在处理PHP请求时,就是将动态请求发送给PHP-FPM模块处理,此处就是反向代理的体现
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
2、环境搭建
本次实验总共需要三台机器,一台作为nginx代理服务器,2台作为后端的web服务器
| IP地址 | 主机名称 | 网络配置 | 配置要求 | 服务器角色 |
|---|---|---|---|---|
| 192.168.217.143 | nginx-proxy | VMnet0,VMNet8(nat) | 1CPU、1GB内存、20G磁盘 | nginx代理服务器 |
| 192.168.217.145 | tomcat-user | VMNet0 | 1CPU、1GB内存、20G磁盘 | web服务器-user项目 |
| 192.168.217.144 | tomcat-admin | VMNet0 | 1CPU、1GB内存、20G磁盘 | web服务器-admin |
VMNet0为内网环境,无法访问外网(hostonly)
VMNet8可以访问外网,提供了统一的入口(net)
注意:搭建环境时,先全部用外网,等环境搭建好了之后,配置网络
三台机器需要完成的事情:
#!/bin/bash
# 1. 设置主机名
hostnamectl set-hostname $1
if [ $1 == 'nginx-proxy' ];then
echo 192.168.120.134 nginx-proxy >> /etc/hosts
echo 192.168.120.135 tomcat-admin >> /etc/hosts
echo 192.168.120.136 tomcat-user >> /etc/hosts
fi
# 2. 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
# 3. 配置yum源
cd /etc/yum.repos.d
mkdir bak
mv *.repo bak
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
yum install epel-release -y
# 4. 重启
reboot
nginx-proxy需要安装nginx:
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
yum install nginx -y
tomcat-user与 tomcat-admin需要安装jdk与tomcat
tar -xf jdk-17_linux-x64_bin.tar.gz -C /usr/local
vim /etc/profile
# 在文件的最后面添加如下内容
export JAVA_HOME=/usr/local/jdk-17.0.12
export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile
tar -xf apache-tomcat-9.0.93.tar.gz -C /usr/local
网络配置:
tomcat-user: VMNet0
查看IP重新连接
tomcat-admin: VMNet0
查看IP重新连接
nginx-proxy: VMNet0,VMNet8
重新设置主机名

3、基本配置及语法
1)语法及常用配置项
模块: ngx_http_proxy_module
指令: proxy_pass
位置: location
作用: 设置代理服务器将请求转发到的协议(http或https)、地址(主机名或IP)以及可选的URI。此指令是proxy模块的核心,用于指定请求应被转发到的后端服务器
常见配置:
proxy_set_header: 设置真实客户端地址
# 设置 Host 头部
proxy_set_header Host $http_host;
# 设置客户端真实 IP 地址(请求的客户机的真实ip)
proxy_set_header X-Real-IP $remote_addr;
# 设置请求的来源 IP 地址链(转发服务器的ip)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect: 转发时是否使用默认端口
proxy_redirect [ default|off|redirect replacement ];
proxy_connect_timeout: Nginx与后端服务器建立连接的超时时间
proxy_read_timeout: Nginx从后端服务器读取响应的超时时间
proxy_send_timeout: Nginx向后端服务器发送的请求超时时间
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 10s;
proxy_buffering: 缓冲开关
proxy_buffer_size: 缓冲区大小
proxy_buffers: 缓冲区数量
proxy_busy_buffers _size: 忙碌的缓冲区大小
proxy_buffering [ on | off ];
proxy_buffer_size 4k|8k;
proxy_busy_buffers 8 4k|8k;
proxy_busy_buffers_size 8k|16k;
2)需求:当请求地址中包含/user时转发到tomcat-user服务器,当地址中包含/admin时转发到tomcat-admin服务器
tomcat-user
cd /usr/local/apache-tomcat-9.0.93/webapps/
rm -rf *
mkdir ROOT
cd ROOT
echo "user" > index.html
cd ../../bin/
./startup.sh
tomcat-admin
cd /usr/local/apache-tomcat-9.0.93/webapps/
rm -rf *
mkdir ROOT
cd ROOT
echo "admin" > index.html
cd ../../bin/
./startup.sh
nginx-proxy
cd /etc/nginx/conf.d/
vim default.conf
location /user/ {
proxy_pass http://tomcat-user:8080/;
}
location /admin/ {
proxy_pass http://tomcat-admin:8080/;
}
systemctl restart nginx
注意1:
proxy_pass http://tomcat-user:8080/ 地址后面带/与不带/是否区别的:
带:如访问的路径为:http://192.168.217.143/user/转发之后为: http://tomcat-user:8080/
不带:如访问的路径为:http://192.168.217.143/user/转发之后为: http://tomcat-user:8080/user/
注意2:
/user/的含义是:http://192.168.217.143/user/a.html 出去协议,IP,端口之后,以/user/开头的请求
/admin/的含义是:http://192.168.217.143/admin/a.html 出去协议,IP,端口之后,以/admin/开头的请求
4、获取真实IP

tomcat 日志中获取的客户端的IP是nginx服务器的IP,这个IP并不是我们想要的结果,而是想要的真实的客户端的IP

在nginx的代理上加上如下配置,nginx-proxy
cd /etc/nginx/conf.d/
vim default.conf
location /user/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://tomcat-user:8080/;
proxy_redirect default;
}
location /admin/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://tomcat-admin:8080/;
proxy_redirect default;
}
systemctl restart nginx
在tomcat-user服务器中更改tomcat日志打印的方式: server.xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Real-IP" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%{X-Real-IP}i %h %l %u %t "%r" %s %b" />
</Host>
重新访问,在查看日志输出:

三、动静分离部署
1、概述
为了提高网站的响应速度,减轻程序服务器(Tomcat,Jboss等)的负载,对于静态资源,如图片、js、css等文件,可以在反向代理服务器中进行缓存,这样浏览器在请求一个静态资源时,代理服务器就可以直接处理,而不用将请求转发给后端服务器。对于用户请求的动态文件,如servlet、jsp,则转发给Tomcat,Jboss服务器处理,这就是动静分离。即动态文件与静态文件的分离。
动静分离可通过location对请求url进行匹配,将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。通常将静态资源放到nginx中,动态资源转发到tomcat服务器中。

2、演示
woniu-car-war.zip来演示动静分离,将静态资源部署在nginx代理服务器,将动态资源部署在tomcat服务器
-
复制静态资源到代理服务器
找到项目的static静态文件所在目录,然后执行下面命令,将static静态资源目录拷贝到nginx代理服务器中
远程复制命令:
scp -r static/ root@nginx-proxy:/usr/share/nginx/html/ -
配置代理服务器的location 路由规则
location ~ /.*\.(js|css|png)$ { root /usr/share/nginx/html/static; } -
到浏览器进行验证,使用F12开发者工具访问静态资源路劲,看资源访问报错提示是哪个服务器

四、负载均衡
1、概述
Nginx是一个高性能的HTTP和反向代理服务器,拥有丰富的功能和模块,负载均衡就是其中之一。负载均衡是一种技术,用于在多台服务器之间分配工作负载,以确保高可用性和可靠性。本文将详细介绍Nginx的负载均衡算法、工作原理、配置方法和实际应用。
负载均衡是指将用户的请求分配到多个后端服务器上进行处理,以达到优化资源利用率、提高响应速度和增加系统的可靠性的目的。负载均衡器通常位于用户和服务器之间,接收用户的请求,并根据某种算法将请求分发给合适的后端服务器

2、配置
http {
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}

upstream server_group_name {
server localhost:8080;
server 192.168.xxx.xxx:8081 down;
server 192.168.xxx.xxx:8082 max_fails=3 fail_timeout=20s;
server 192.168.xxx.xxx:8083;
# 启用了主动式健康检查。健康检查的间隔时间为10秒,超时时间为5秒,连续失败3次认为服务器不可用,连续成功2次认为服务器恢复可用
health_check interval=10s timeout=5s fails=3 passes=2;
}
3、算法
1)轮询
轮询(Round Robin)策略是 Nginx 配置中默认的负载均衡策略,该策略将客户端的请求依次分配给后端的服务器节点,对后端集群中的服务器实现轮流分配。轮询策略绝对均衡,且实现简单,但也会因后端服务器处理能力的不同而影响整个集群的处理性能
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
加权轮询(Weighted Round Robin)在 Nginx 的轮询策略中,为了避免因集群中服务器性能的差异对整个集群性能造成影响,在轮询策略的基础上增加了权重参数,让使用者可以手动根据集群中各服务器的性能将请求数量按照权重比例分配给不同的被代理服务器
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
2)一致性哈希
Nginx 启用哈希的负载均衡策略,是用 hash 指令来设置的。哈希策略方法可以针对客户端访问的 URL 计算哈希值,对相同的 URL 请求,Nginx 可以因相同的哈希值而将其分配到同一后端服务器。当后端服务器为缓存服务器时,将极大提高命中率,提升访问速度。 一致性哈希的优点是,可以使不同客户端的相似请求发送给同一被代理服务器,当被代理服务器为缓存服务器场景应用时,可以极大提高缓存的命中率。 一致性哈希的缺点是,当上游服务器组中的节点数量发生变化时,将导致所有绑定被代理服务器的哈希值重新计算,影响整个集群的绑定关系,产生大量回源请求。
upstream backend {
hash $request_uri; # 以客户端请求URI为计算哈希值的ke
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
3)IP哈希
IP 哈希(IP Hash)负载均衡策略根据客户端IP计算出哈希值,然后把请求分配给该数值对应的被代理服务器。在哈希值不变且被代理服务器可用的前提下,同一客户端的请求始终会被分配到同一台被代理服务器上。IP 哈希负载均衡策略常被应用在会话(Session)保持的场景。 HTTP 客户端在与服务端交互时,因为 HTTP 协议是无状态的,所以任何需要上下文逻辑的情景都必须使用会话保持机制,会话保持机制是通过客户端存储由唯一的 Session ID 进行标识的会话信息,每次与服务器交互时都会将会话信息提交给服务端,服务端依照会话信息实现客户端请求上下文的逻辑关联。
会话信息通常存储在被代理服务器的内存中,如果负载均衡将客户端的会话请求分配给其他被代理服务器,则该会话逻辑将因为会话信息失效而中断。所以为确保会话不中断,需要负载均衡将同一客户端的会话请求始终都发送到同一台被代理服务器,通过会话保持实现会话信息的有效传递。
upstream backend {
ip_hash; # 启用IP哈希负载均衡策略
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
4)最少连接
默认配置下轮询算法是把客户端的请求平均分配给每个被代理服务器,每个被代理服务器的负载大致相同,该场景有个前提就是每个被代理服务器的请求处理能力是相当的。如果集群中某个服务器处理请求的时间比较长,那么该服务器的负载也相对增高。在最少连接(least_conn)负载均衡策略下,会在上游服务器组中各服务器权重的前提下将客户端请求分配给活跃连接最少的被代理服务器,进而有效提高处理性能高的被代理服务器的使用率
upstream backend {
least_conn; # 启用最少连接负载均衡策略
server backend1.example.com weight=3;
server backend2.example.com weight=1;
}
4、案例
通过案例演示nginx不同负载均衡策略的实验
五、基于nginx的负载均衡
1、OSI 模型
OSI 模型(Open System Interconnection Model)是一个由国际标准化组织(ISO)提出的概念模型,试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的接口。了解 OSI 模型有助于理解实际上互联网络的工业标准------TCP/IP 协议。 OSI采用了分层的结构化技术,共分七层:
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

2、七层负载
七层负载,也称为应用层负载均衡,主要在网络模型的第七层(应用层)上工作。它处理HTTP、HTTPS等协议的流量,并根据应用层协议的信息来进行流量分发和负载调度。七层负载均衡可以实现更高级的功能,如URL重写、会话保持、SSL卸载等。在Nginx中,七层负载均衡是通过http模块实现的。
http {
upstream backend_http {
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_http;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
在这个配置中,
http块定义了一个七层负载均衡上下文。upstream块定义了一个名为backend_http的后端服务器组,包含两个服务器。server块监听80端口,并将流量代理到backend_http服务器组。location块指定了将所有请求代理到后端服务器组,并设置了一些代理相关的参数,如请求头
3、四层负载
四层负载,也称为传输层负载均衡,主要在网络模型的第四层(传输层)上工作。它处理TCP/UDP协议的流量,并根据报文中的目标地址和端口,以及负载均衡设备设置的服务器选择方式,来决定最终选择的内部服务器。四层负载均衡能够拿到的数据只有IP和端口,无法对流量大小进行区分。在Nginx中,四层负载均衡是通过stream模块实现的。
stream {
upstream backend_tcp {
server backend1.example.com:8080;
server backend2.example.com:8080;
}
server {
listen 80;
proxy_pass backend_tcp;
}
}
http{
...
}
在这个配置中,
stream块定义了一个四层负载均衡上下文。upstream块定义了一个名为backend_tcp的后端服务器组,包含两个服务器。server块监听80端口,并将流量代理到backend_tcp服务器组注意:这里需要安装Nginx 1.9及以上版本,1.9及以上版本Nginx才支持四层路由TCP/UDP转发,并在编译安装时开启---with-stream模块
4、四层负载实验
需求:通过nginx的4层负载均衡,实现SSH服务的代理

stream { #四层代理配置stream
upstream backend { #定义集群,名称为backend
server 192.168.1.20:22; #代理的是ssh服务,所以是22端口
server 192.168.1.30:22;
}
server { #定义一个本地服务器代理服务
listen 12345; #本地代理监听端口,需要是未使用的端口
proxy_pass backend; #调用backend集群,集群名要与上面定义的对应
}
}
http {
... ...
}
客户端测试:
使用MX远程连接nginx4层代理服务器的12345端口,会自动转发到web1和web2的22端口:
六、综合练习
需求:实现对woniu-car项目的负载均衡
1. 总共三台服务器,1台nginx服务器,2台tomcat服务器
2. nginx实现7层负载均衡,使用加权轮询的算法进行负载
课堂小结
-
正向代理与反向代理讲解
-
nginx反向代理配置
-
nginx-tomcat实现动静分离部署
-
负载均衡概述及负载策略
-
nginx-tomcat实现负载均衡
课后作业
-
完成课堂的案例及练习
-
将今天的内容整理为思维导图的形式
-
完成以下面试题
1、nginx负载均衡有哪些策略,特点是什么?
2、正向代理与反向代理的区别是什么?
3、四层代理与七层代理的区别是什么?
4、使用nginx方向代理之后,在web服务器端如何获取客户端真实IP?
扩展内容
无