Nginx详解 第五部分:Ngnix反向代理(负载均衡 动静分离 缓存 透传 )

Part 5

  • 一、正向代理与反向代理
    • [1.1 正向代理简介](#1.1 正向代理简介)
    • [1.2 反向代理简介](#1.2 反向代理简介)
  • 二、配置反向代理
    • [2.1 反向代理配置参数](#2.1 反向代理配置参数)
      • [2.1.1 proxy_pass](#2.1.1 proxy_pass)
      • [2.1.2 其余参数](#2.1.2 其余参数)
    • [2.2 配置实例:反向代理单台web服务器](#2.2 配置实例:反向代理单台web服务器)
    • [2.3 代理转发](#2.3 代理转发)
  • 三、反向代理实现动静分离
  • 四、缓存功能
  • 五、反向代理客户端的IP透传
    • [5.1 原理概述](#5.1 原理概述)
    • [5.2 一级代理](#5.2 一级代理)
    • [5.3 多级代理](#5.3 多级代理)
  • 六、反向代理负载均衡
    • [6.1 工作原理](#6.1 工作原理)
    • [6.2 部分配置参数](#6.2 部分配置参数)
    • [6.3 调度算法](#6.3 调度算法)
    • [6.4 配置实例](#6.4 配置实例)
      • [6.4.1 使用轮询算法](#6.4.1 使用轮询算法)
      • [6.3.2 使用加权轮询](#6.3.2 使用加权轮询)
      • [6.3.3 备份-----使用backup参数](#6.3.3 备份-----使用backup参数)

一、正向代理与反向代理

1.1 正向代理简介

什么是正向代理?

正向代理代理的是客户端。

客户端设备要访问局域网以外的 Internet 时,需在客户端浏览器中配置代理服务器,然后通过代理服 务器来进行访问,将访问到的局域网以外的 Internet 网站内容返回给客户端,而不是通过局域网中的客 户端设备直接访问。

正向代理的用途

访问原来无法访问的资源;

可做缓存,加速访问资源;

对客户端访问授权,上网进行认证;

代理可以记录用户访问记录等,且对外隐藏用户信息。

简单配置

java 复制代码
server {
    listen 80;
    server_name ....;#客户端访问的域名或IP地址

    location / {
      proxy_pass http://目标服务器地址;
    }
  }

1.2 反向代理简介

bash 复制代码
官方文档https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 

什么是反向代理?

反向代理代理的是服务端。

在使用反向代理时,客户端向一个服务器发送请求,而实际上该请求会被转发到后端的多个真实服务器(也称为上游服务器),然后由反向代理服务器来处理请求并将结果返回给客户端。

客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址。

反向代理能实现的功能

反向代理的主要作用是提供负载均衡和高可用性。

负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。

缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。

动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。

多站点代理:Nginx可以代理多个域名或虚拟主机,将不同的请求转发到不同的后端服务器上,实现多个站点的共享端口。

反向代理的可用模块

bash 复制代码
ngx_http_proxy_module     
#将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module 
#用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module  
#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module  
#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module    
#将客户端对Python的请求以uwsgi协议转发至指定服务器处理

二、配置反向代理

2.1 反向代理配置参数

2.1.1 proxy_pass

bash 复制代码
proxy_pass 地址:端口的方式 ;  
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
bash 复制代码
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
bash 复制代码
proxy_pass http://10.0.0.18:8080; 和 
proxy_pass http://10.0.0.18:8080/;主要有以下区别:

1. 尾部斜杠的处理:在 `proxy_pass` 指令中,尾部斜杠的有无会影响代理的行为。当 `proxy_pass` 后跟一个斜杠 `/` 时,表示将请求的 URI 附加到代理服务器的地址后面。而当 `proxy_pass` 后没有斜杠时,请求的 URI 将被完全忽略,并将直接转发到指定的代理服务器。

   - `proxy_pass http://10.0.0.18:8080;`:请求将直接转发到 `http://10.0.0.18:8080`,不附加任何 URI。
   - `proxy_pass http://10.0.0.18:8080/;`:请求将被附加上原始 URI,并转发到 `http://10.0.0.18:8080`。

2. 请求路径的保留:当使用 `proxy_pass` 指令时,代理服务器会保留原始请求的路径信息。这意味着,无论使用哪种形式,原始请求的路径将被传递到目标服务器。只是在转发时是否附加原始路径的处理不同。
 

2.1.2 其余参数

bash 复制代码
proxy_hide_header field;
#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置

proxy_pass_header field;
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果
要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段`
proxy_pass_header Server;
proxy_pass_header Date;


proxy_pass_request_body on | off; 
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启


proxy_pass_request_headers on | off; 
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启

2.2 配置实例:反向代理单台web服务器

配置部分

bash 复制代码
7-1   代理服务器 

vim /apps/nginx/conf.d/computer.conf
#添加
location  / {
    proxy_pass http://192.168.2.102;
}
bash 复制代码
7-2   真实服务器 

yum  install   httpd  -y #安装服务

cd  /var/www/html
echo   "Hello World"  > index.html #主页内容

systemctl	start httpd #开启服务
bash 复制代码
7-3   客户机

vim  /etc/hosts
192.168.2.100  www.byyb.com

测试部分

7-3(客户端)访问 7-2(代理服务器)

bash 复制代码
curl 192.168.2.100

2.3 代理转发

要求:将用户对域 www.byyb.com的请求转发给后端服务器处理

nginx 复制代码
7-1 代理服务器

vim /apps/nginx/conf.d/comupter.conf
#添加
location ~* / {
   proxy_pass http://192.168.2.102;
   }
#用正则表达式 后面不能用 / ,

三、反向代理实现动静分离

因为nginx无法处理动态资源,所以要动静分离。

指定location 实现反向代理 动静分离。

配置部分

nginx 复制代码
7-1 代理服务器

编辑子配置文件
vim /apps/nginx/conf.d/computer.conf
bash 复制代码
7-2 动态资源服务器

#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0

#安装服务
yum install -y epel-release #依赖
yum install nginx -y 
systemctl start nginx 

#创建动态资源目录
cd /usr/share/nginx/html
mkdir api
echo api > ./api/index.html
bash 复制代码
7-4 静态资源服务器

#关闭防火墙和selinux
systemctl stop firewalld ; setenforce 0

#安装服务
yum install -y epel-release #依赖
yum install nginx -y 
systemctl start nginx 

#创建静态资源目录
cd /usr/share/nginx/html
mkdir static
echo static > ./static/index.html

测试部分

bash 复制代码
7-3客户端

#关闭防火墙和selinux
systemctl stop firewalld ; setenforce 0

#动态资源
curl 192.168.2.100/api -L

#静态资源
curl 192.168.2.100/static -L

四、缓存功能

反向代理可以缓存静态资源,如图片、CSS和JavaScript文件等。

当客户端再次请求相同资源时,反向代理可以直接返回缓存中的响应,减少对后端服务器的请求压力,并加快响应速度。

bash 复制代码
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义

proxy_cache_key string;
#缓存中用于"键"的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;



proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
 示例:
 proxy_cache_valid 200 302 10m;
 proxy_cache_valid 404 1m;
 
 
 
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http 
proxy_cache_path path [levels=levels] [use_temp_path=on|off] 
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number] 
[manager_sleep=time] [manager_threshold=time] [loader_files=number] 
[loader_sleep=time] [loader_threshold=time] [purger=on|off] 
[purger_files=number] [purger_sleep=time] [purger_threshold=time];


#示例:在http配置定义缓存信息
   proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
   levels=1:2:2 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
   keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key
   inactive=120s  #缓存有效时间  
   max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
   
   
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m;   #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存


proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | 
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;


proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
bash 复制代码
proxy_cache_path /data/nginx/proyxcache   levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;

#上面那段写在 http语句

:1:1  16个二进制


server {
   listen 80;
   proxy_cache proxycache;
   proxy_cache_key $request_uri;
   #proxy_cache_key $host$uri$is_args$args;
   proxy_cache_valid 200 302 301 10m;
   proxy_cache_valid any 5m;
   server_name www.kgc.com;
   root /data/nginx/pc;
  location / {
  root /data/nginx/pc;
  }
  location /api {
  proxy_pass http://192.168.91.101:9527;
  }
  location ~* \.(jpg|png|gif|html)$ {
  proxy_pass http://192.168.91.102;
  }

}

五、反向代理客户端的IP透传

5.1 原理概述

反向代理客户端IP透传是指在使用反向代理服务器时,将客户端的真实IP地址传递给后端服务器。

这可以通过一些特定的 HTTP 头字段来实现,比如 X-Forwarded-For (XFF) 头字段。

当请求经过反向代理服务器时,代理服务器会将客户端的真实IP地址添加到 XFF 头字段中,然后转发给后端服务器。

5.2 一级代理

配置部分

bash 复制代码
7-1 代理服务器

#编辑子配置文件
vim /apps/nginx/conf.d/computer.conf
#修改location部分
 location / {
   index index.html index.php;
   root /data/nginx/html/pc;
   proxy_pass http://192.168.2.102;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}
#####
`$proxy_add_x_forwarded_for` 是一个 nginx 变量,用于获取客户端的真实 IP 地址并将其添加到请求中的 `X-Forwarded-For` 头字段中,后端服务器可以通过检查该头字段来获取请求的真实客户端 IP 地址。

`X-Forwarded-For` 头字段是一个常用的 HTTP 请求头,用于指示请求的真实客户端 IP 地址。
bash 复制代码
7-2 后端服务器

#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0

#安装服务
yum install -y epel-release #依赖
yum install nginx -y 
systemctl start nginx 

测试部分

bash 复制代码
7-3客户端,访问代理服务器
curl 192.168.2.100
bash 复制代码
7-2 后端服务器,查看日志
cat /var/log/nginx/access.log | tail -n -2

5.3 多级代理

bash 复制代码
7-3 客户端     192.168.2.103

7-2 真实服务器   192.168.2.102

7-1 第1个代理服务器   192.168.2.100

7-4 第2个代理服务器   192.168.2.74 

配置部分

bash 复制代码
7-1 一级代理服务器

#编辑子配置文件
vim /apps/nginx/conf.d/computer.conf
#反向代理指向7-4的IP
bash 复制代码
nginx -t  #语法检查
nginx -s reload #重载
bash 复制代码
7-4 二级代理服务器

#yum安装nginx
#编辑主配置文件
vi /etc/nginx/nginx.conf

server {
location / {
proxy_pass http://192.168.2.102;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
bash 复制代码
nginx -t  #语法检查
nginx -s reload #重载
bash 复制代码
7-2 后端服务器

#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0

#安装服务
yum install -y epel-release #依赖
yum install nginx -y 
systemctl start nginx 

测试部分

bash 复制代码
7-3客户端,访问代理服务器
curl 192.168.2.100
bash 复制代码
7-2 后端服务器,查看日志
cat /var/log/nginx/access.log | tail -n -1

六、反向代理负载均衡

Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能。

bash 复制代码
官方文档
https://nginx.org/en/docs/http/ngx_http_up

6.1 工作原理

Nginx负载均衡通过将传入的请求分发到多个后端服务器来实现负载均衡。

它可以根据不同的调度算法(如轮询、IP哈希、最小连接数等)将请求分发到后端服务器。

6.2 部分配置参数

bash 复制代码
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:

weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等

max_conns=number  #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number  #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测

fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒



sorry server   自己不能转自己

down    #标记为down状态

resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
bash 复制代码
backup  #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 

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

6.3 调度算法

1)轮询(Round Robin):这是默认的调度算法,Nginx依次分配每个请求给后端服务器,实现简单且公平的请求分发。

bash 复制代码
http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
    }
    
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
}

2)加权轮询(Weighted Round Robin):通过为每个后端服务器指定一个权重,根据权重比例来分配请求。具有更高权重的服务器将获得更多的请求。

bash 复制代码
http {
    upstream backend {
        server backend1.example.com weight=3;
        server backend2.example.com weight=1;
    }
    
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }

}

3)IP Hash:根据客户端的IP地址进行散列,将同一IP的请求分配给同一台后端服务器,实现会话保持。

bash 复制代码
http {
    upstream backend {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
    }
    
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
}

4)URL哈希(URL Hash):基于请求的URL进行散列计算,将相同URL的请求分发到同一台后端服务器,用于缓存或会话的需要。

bash 复制代码
http {
    upstream backend {
        hash $request_uri;
        server backend1.example.com;
        server backend2.example.com;
    }
    
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
}

5)参数哈希(Parameter Hash):基于请求的特定参数进行散列计算,将具有相同参数值的请求分发到同一台后端服务器。

6)最小连接数(Least Connections):将请求分发给连接数最少的服务器,以确保服务器的负载尽可能均衡。

bash 复制代码
http {
    upstream backend {
        least_conn;
        server backend1.example.com;
        server backend2.example.com;
    }
    
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
}

7)最少响应时间(Least Time):根据服务器的响应时间进行选择,将请求分配给响应时间最短的服务器。

6.4 配置实例

要启用负载均衡,需要在Nginx主配置文件中添加一个upstream块来定义后端服务器的列表。

然后,在相应的location块中使用proxy_pass指令指定负载均衡的上游服务器。

6.4.1 使用轮询算法

配置部分

以后端服务器7-2和7-4为例

7-2 :192.168.2.100

7-4:192.168.2.104

bash 复制代码
7-1 代理服务器

#主配置文件中 http部分  写在日志下面
#先定义group1组

vim /apps/nginx/conf/nginx.conf

upstream group1{
    server 192.168.2.102;
    server 192.168.2.104;
}
bash 复制代码
#修改子配置文件
#修改location部分,加入
    pass_proxy http://group1/;

测试部分

bash 复制代码
#清空7-2和7-4的access.log
echo " " > /var/log/nginx/access.log

#实时追踪日志
tail -f /var/log/nginx/access.log


#切换到客户端,多次访问代理服务器7-1
curl 192.168.2.100 
#访问n次,观察7-2和7-4的日志

6.3.2 使用加权轮询

配置部分

bash 复制代码
7-1 代理服务器

#修改主配置文件
vim /apps/nginx/conf/nginx.conf

upstream group1{
    server 192.168.2.102 weight=3;
    server 192.168.2.104 weight=1;
}

测试部分

bash 复制代码
#清空7-2和7-4的access.log
echo " " > /var/log/nginx/access.log

#实时追踪日志
tail -f /var/log/nginx/access.log


#切换到客户端,多次访问代理服务器7-1
curl 192.168.2.100 
#访问n次,观察7-2和7-4的日志

6.3.3 备份-----使用backup参数

当所有后端服务器不可用时,才会启用此备用服务器

配置部分

bash 复制代码
7-1 代理服务器

#修改主配置文件
vim /apps/nginx/conf/nginx.conf

upstream group1{
    server 192.168.2.102 ;
    server 192.168.2.104 backup;
}
#104为备
bash 复制代码
7-2 后端服务器 主
#修改主页
echo "State Visit BYYB" > /usr/share/nginx/html/index.html
bash 复制代码
7-4 后端服务器作为备份服务器

#修改主页
echo "State Backup BYYB" > /usr/share/nginx/html/index.html

测试部分

bash 复制代码
浏览器访问
192.168.2.100
bash 复制代码
关闭7-2,再次访问,观察变化
相关推荐
愚润求学5 分钟前
【Linux】网络基础
linux·运维·网络
bantinghy35 分钟前
Linux进程单例模式运行
linux·服务器·单例模式
MonkeyKing_sunyuhua36 分钟前
Guava Cache 本地项目缓存
缓存·guava
小和尚同志1 小时前
29.4k!使用 1Panel 来管理你的服务器吧
linux·运维
帽儿山的枪手2 小时前
为什么Linux需要3种NAT地址转换?一探究竟
linux·网络协议·安全
就叫飞六吧9 天前
基于keepalived、vip实现高可用nginx (centos)
python·nginx·centos
shadon1789 天前
回答 如何通过inode client的SSLVPN登录之后,访问需要通过域名才能打开的服务
linux
小米里的大麦9 天前
014 Linux 2.6内核进程调度队列(了解)
linux·运维·驱动开发
程序员的世界你不懂9 天前
Appium+python自动化(三十)yaml配置数据隔离
运维·appium·自动化
算法练习生9 天前
Linux文件元信息完全指南:权限、链接与时间属性
linux·运维·服务器