赞
踩
目录
概念:正向代理是位于客户端和目标服务器之间的代理服务器,代表客户端向目标服务器发送请求。客户端将请求发送给代理服务器,然后代理服务器将请求转发给目标服务器,并将响应返回给客户端
作用:隐藏客户端的真实 IP 地址,访问受限网站、保护客户端隐私、提高访问速度等。
示例:企业内部网络中的代理服务器、翻墙工具
概念:反向代理是位于目标服务器和客户端之间的代理服务器,代表目标服务器向客户端返回响应。客户端发送请求给反向代理,反向代理根据配置将请求转发给相应的目标服务器,然后将目标服务器的响应返回给客户端。
作用:负载均衡、安全防护、缓存加速、隐藏服务器真实 IP 地址等。
示例:CDN(内容分发网络)、负载均衡器、应用服务器集群等
区别 | 正向代理 | 反向代理 |
---|---|---|
位置 | 位于客户端和目标服务器之间 | 位于目标服务器和客户端之间 |
目的 | 代理客户端向外部服务器发送请求 | 代理服务器向客户端返回响应 |
隐藏对象 | 隐藏客户端的真实 IP 地址 | 隐藏服务器的真实 IP 地址 |
常见应用 | 翻墙、保护隐私等个人使用场景 | 负载均衡、安全防护等企业和网站运维场景 |
在于代理服务器与目标服务器之间使用的协议是否相同
同构代理与目标服务器具有相同的协议,而异构代理则使用与目标服务器不同的协议
四层代理(也称为传输层代理):四层代理工作在OSI模型的传输层,主要指TCP/UDP 协议,负责数据的传输和端到端的通信。它们通常基于IP地址和端口号进行路由和负载均衡。四层代理不关心应用层的协议,只关心数据包的源和目的
七层代理(也称为应用层代理):七层代理工作在OSI模型的应用层,可以理解和处理HTTP、FTP、SMTP等应用层协议。它们可以根据应用层的信息(如URL、Cookie、报文头等)进行路由和负载均衡
四层代理(也称为传输层代理)原理:使用 NAT(Network Address Translation)技术,即网络地址转换。即请求进来的时候,nginx 只修改数据包里面的目标IP、源IP、端口,然后就直接把数据包发给目标服务器(即nginx不知道请求的具体内容),目标服务器处理完成后,发给 nginx,nginx 数据包再做一次类似的修改,就返回给请求的客户端了
七层代理(也称为应用层代理)原理:nginx 读取并解析 Http 请求内容,然后将具体内容(请求行、请求头、空行、请求数据)转发到相应的服务器,转发的过程是:建立和目标机器的连接,然后转发请求,收到响应数据再转发给请求客户端
官方文档: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
模块 | 功能 |
---|---|
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协议转发至指定服务器处理 |
- proxy_pass;
- #用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
- 地址:端口的方式
- #也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
前提:关闭所有设备的防火墙和核心防护,以及开启反向代理服务器的nginx服务
- [root@localhost ~]#systemctl stop firewalld
- [root@localhost ~]#setenforce 0
- [root@localhost ~]#systemctl start nginx
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server{
- listen 80;
- server_name www.dh.com;
- root /mnt;
- location / {
- proxy_pass http://172.16.12.12; #访问本机的根等于访问指定目的服务器的根
- }
- }
- [root@localhost ~]#nginx -s reload
- [root@localhost ~]#echo "welcome to proxy_server" > /mnt/index.html
目的服务器配置:
- [root@localhost ~]#yum install -y httpd
- [root@localhost ~]#systemctl start httpd
- [root@localhost ~]#cd /var/www/html/
- [root@localhost html]#vim index.html
- <html>
- <body>
- <h1>welcome to destination_server </h1>
- </body>
客户端测试:
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server{
- listen 80;
- server_name www.dh.com;
- root /mnt;
- location / {
- proxy_pass http://172.16.12.12:9527;
- }
- }
- [root@localhost ~]#nginx -s reload
目的服务器配置:
- [root@localhost ~]#vim /etc/httpd/conf/httpd.conf
- Listen 9527
- [root@localhost ~]#systemctl restart httpd
客户端测试:
表示服务器作为网关或代理,收到目的服务器的无效响应。当请求通过代理服务器转发到目的服务器时,如果代理服务器收到目的服务器的响应无效(例如无响应,格式错误等),就会返回502错误给客户端。通常,这种错误表明目的服务器无法正常工作或响应异常
模拟一:给目的服务器作防火墙规则
- [root@localhost ~]#iptables -A INPUT -s 172.16.12.10 -j REJECT
- #客户端再次访问,会出现502,一般出现502代表目的服务器挂了
- [root@localhost ~]#iptables -vnL --line-numbers
客户端测试:
模拟二:直接关闭目的服务器
[root@localhost ~]#systemctl stop httpd
客户端测试:
表示服务器作为网关或代理,但在完成请求时等待响应超时。当客户端向代理服务器发送请求后,代理服务器将请求转发给目的服务器,但在规定的时间内未能从目的服务器获取到响应,就会返回504错误给客户端。这可能是由于目的服务器过载、响应时间过长或网络连接问题导致
模拟一:给目的服务器作防火墙规则
- [root@localhost ~]#iptables -R INPUT 1 -s 172.16.12.10 -j DROP
- #客户端再次访问会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间
- [root@localhost ~]#iptables -vnL --line-numbers
客户端测试:
情况一:当代理服务器配置文件不加/
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server{
- listen 80;
- server_name www.dh.com;
- root /mnt;
- location /api {
- proxy_pass http://172.16.12.12;
- }
- }
- [root@localhost ~]#nginx -s reload
- [root@localhost ~]#mkdir /mnt/api
- [root@localhost ~]#echo "api api api api" > /mnt/api/index.html
目的服务器配置:
- [root@localhost ~]#mkdir /var/www/html/api/
- [root@localhost ~]#echo "api api api api" > /var/www/html/api/index.html
情况二:当代理服务器配置文件加/
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server{
- listen 80;
- server_name www.dh.com;
- root /mnt;
- location /api {
- proxy_pass http://172.16.12.12/;
- }
- }
- [root@localhost ~]#nginx -s reload
总结:
- 是否在代理目标后面添加斜杠
/
主要取决于后端服务器对请求 URI 的要求- 不使用
/
作为代理目标,Nginx 会将匹配到的 URI 去除掉,然后将剩余部分添加到代理目标中如果后端服务器只需要请求 URI 的一部分,就不需要添加斜杠
/
- 使用
/
作为代理目标时,Nginx 会将请求的 URI 原封不动地发送到代理服务器如果后端服务器期望接收完整的请求 URI,就需要在代理目标后面加上斜杠
/
注:
/api能匹配的可能性太多,一般不加/,不允许替换,只能追加
静态资源:静态资源是指在服务器上事先准备好的,内容不会随着用户请求的变化而变化的资源。它们在服务器上存储为静态文件,并通过 HTTP 协议直接提供给用户。常见的静态资源包括 HTML 文件、CSS 样式文件、JavaScript 文件、图像文件、字体文件等。这些文件的内容不会随请求的变化而改变。
动态资源:动态资源是指在服务器端根据用户请求的参数或其他信息生成的,内容可能会随着请求的变化而变化的资源。它们需要服务器端的处理逻辑来生成最终的响应。常见的动态资源包括动态网页、动态图片生成、个性化内容等。这些资源的内容是根据用户的请求和服务器端的处理逻辑动态生成的
反向代理服务器进行动静分离是为了提高网站性能和用户体验。动静分离指的是将动态内容和静态内容分开处理,以便更有效地管理和优化它们
目的服务器1(静态资源处理)配置:
- [root@localhost ~]#yum install -y httpd
- [root@localhost ~]#systemctl start httpd
- [root@localhost ~]#cd /var/www/html
- [root@localhost ~]#echo "static resources" > index.html
- [root@localhost html]#ls #再放入一张图片
- 1.jpg index.html
目的服务器2(动态资源处理)配置:
- [root@localhost ~]#yum install -y httpd
- [root@localhost ~]#systemctl start httpd
- [root@localhost ~]#mkdir /var/www/html/api/
- [root@localhost ~]#echo "dynamic resources" > /var/www/html/api/index.html
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- location ~* \.(jpg|jpeg|png|gif|bmp|html|mp4|txt)$ {
- proxy_pass http://172.16.12.12;
- }
- location ~* /api {
- proxy_pass http://172.16.12.13;
- }
- }
- [root@localhost ~]#nginx -s reload
客户端测试:
当访问静态资源时,代理服务器分析并将请求转送到目的服务器1进行处理
当访问动态资源时,代理服务器分析并将请求转送到目的服务器2进行处理
- proxy_cache zone_name | off; 默认off
- #指明调用的缓存,或关闭缓存机制;Context:http, server, location
- #zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
反向代理服务器配置:
主配置文件配置:
- [root@localhost ~]# vim /apps/nginx/conf/nginx.conf
- proxy_cache_path /opt/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
- #开启缓存 缓存路径 生成文件夹比例是3级 从内存中借调20M专门存放缓存 有效期120秒 最大存储空间为1g
- [root@localhost ~]# nginx -s reload
- [root@localhost ~]# mkdir /opt/nginx/
[root@localhost opt]#mkdir /opt/nginx #还要新建存放缓存对应的目录
子配置文件配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- proxy_cache proxycache;
- proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
- #proxy_cache_key $host$uri$is_args$args;
- proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
- proxy_cache_valid any 5m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
- location ~* \.(jpg|jpeg|png|gif|bmp|html|mp4|txt)$ {
- proxy_pass http://172.16.12.12;
- }
- location ~* /api {
- proxy_pass http://172.16.12.13;
- }
- }
- [root@localhost ~]#nginx -s reload
测试:客户端访问代理服务器
查看代理服务器的缓存内容
测试:关闭目的服务器1和目的服务器2的apache服务
[root@localhost ~]#systemctl stop httpd
客户端还能访问到请求的资源
代理服务器自定义添加响应报文头部信息通常是为了增强安全性、保护隐私、优化性能、过滤或修改内容,以及确保遵守特定的规范和标准
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- 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;
- add_header ip $server_addr; #当前nginx主机ip
- add_header status $upstream_cache_status; #是否缓存命中,hit命中,miss未命中
- add_header name $server_name; #客户端访问的FQDN
- location ~* \.(jpg|jpeg|png|gif|bmp|html|mp4|txt)$ {
- proxy_pass http://172.16.12.12;
- }
- location ~* /api {
- proxy_pass http://172.16.12.13;
- }
- }
- [root@localhost ~]#nginx -s reload
客户端测试:查看新增头部字段信息
[root@localhost html]#curl 172.16.12.10/1.jpg -I
在Nginx中,代理客户端IP透传是指将客户端的真实IP地址(也称为远程IP地址)传递给目的服务器。这在一些情况下非常有用,例如,当Nginx作为反向代理服务器时,我们希望目的服务器能够获取到客户端的真实IP地址,而不是Nginx服务器的IP地址
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- location / {
- proxy_pass http://172.16.12.12;
- }
- }
- [root@localhost ~]#nginx -s reload
目的服务器配置:
[root@localhost ~]#echo "welcome to my world" > /var/www/html/index.html
- #修改日志格式,使之能显示访问的客户端的IP
- [root@localhost ~]#vim /etc/httpd/conf/httpd.conf
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined
- [root@localhost ~]#systemctl restart httpd
测试:
客户端访问代理服务器
查看目的服务器的日志信息,现在没有显示访问的客户端的ip地址
[root@localhost var]#tailf /var/log/httpd/access_log
反向代理服务器配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- #添加客户端IP和反向代理服务器IP到请求报文头部
- location / {
- proxy_pass http://172.16.12.12;
- }
- }
- [root@localhost ~]#nginx -s reload
测试:
客户端再次访问代理服务器,并查看目的服务器的日志信息,现在可看到客户端的ip地址
[root@localhost var]#tailf /var/log/httpd/access_log
反向代理服务器1配置:
- [root@localhost ~]#vim /apps/nginx/conf.d/dh.conf
- server {
- listen 80;
- server_name www.dh.com;
- root /mnt/;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- #添加客户端IP和反向代理服务器IP到请求报文头部
- location / {
- proxy_pass http://172.16.12.11;
- }
- }
- [root@localhost ~]#nginx -s reload
反向代理服务器2配置:
- [root@localhost ~]#yum install -y nginx
- [root@localhost ~]#vim /etc/nginx/nginx.conf
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- location / {
- proxy_pass http://172.16.12.12;
- }
- [root@localhost ~]#systemctl start nginx
测试:客户端访问反向服务器1,并查看目的服务器的日志信息,现在可看到客户端的ip地址
[root@localhost var]#tailf /var/log/httpd/access_log
Nginx 可以将客户端的请求转发至单台后端服务器,但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于 ngx_http_upstream_module 模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
负载均衡相关指令:
- 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秒
-
- backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 sorry server 自己不能转自己
-
- down #标记为 down 状态
-
- resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
配置格式:
- http {
- upstream web {
- server 172.16.12.10 weight=5;
- server 172.16.12.11;
- server 172.16.12.12;
- least_conn;
- ip_hash;
- keepalive 32;
- fair;
- }
- }
-
- server {
- listen 80;
- server_name www.dh.com;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- root /mnt/;
- location / {
- proxy_pass http://web/
- }
- }
上面的配置中,upstream块定义了后端服务器的列表和负载均衡算法。server块定义了反向代理服务器的监听端口和域名,以及请求转发的配置。具体说明如下:
轮询(Round Robin)算法:按照顺序将请求依次分配给后端服务器,每个服务器轮流处理请求。这是一种简单且公平的负载均衡算法
加权轮询(Weighted Round Robin)算法:根据服务器的处理能力(权重)来分配请求,处理能力越高的服务器分配到的请求越多
加权最小连接数(Weighted Least Connections)算法:结合了加权和最小连接数算法,根据服务器的权重和当前连接数来进行请求的分配
hash算法:
ip_hash算法:根据客户端的IP地址计算哈希值,然后将请求分配给特定的服务器。
url_hash算法:据请求的URL来进行负载均衡,负载均衡器会根据请求的URL计算哈希值,然后使用这个哈希值来确定将请求发送到哪一台服务器上
cookie hash算法:根据请求中的特定Cookie来进行负载均衡,负载均衡器会提取请求中的特定Cookie的数值,计算哈希值,然后使用这个哈希值来确定将请求发送到哪一台服务器上
默认算法是轮询算法即反向代理服务器处理用户请求时,每个后端服务器都轮流提供响应
反向代理服务器配置:
- [root@localhost proyxcache]#rm -rf /apps/nginx/conf.d/dh.conf
- [root@localhost proyxcache]#vim /apps/nginx/conf/nginx.conf
- http {
- upstream web {
- server 172.16.12.12;
- server 172.16.12.13;
- }
-
-
- location / {
- proxy_pass http://web/;
- index index.html index.htm;
- }
- [root@localhost proyxcache]#nginx -s reload
目的服务器1配置:
[root@localhost ~]#echo "welcome to server1" > /var/www/html/index.html
目的服务器2配置:
[root@localhost ~]#echo "welcome to server2" > /var/www/html/index.html
客户端测试:
注:
在真实环境中,客户端访问,然后代理服务器根据负载均衡去转发到目的服务器(所有的目的服务器的文件资源是一样的),这里不一样只是为了方便区分调用了哪台目的服务器
模拟目的服务器1宕机,那么访问的结果是什么呢?
- #目的服务器1关闭apache服务
- [root@localhost ~]#systemctl stop httpd
反向代理服务器配置:
- http {
- upstream web {
- server 172.16.12.12;
- server 172.16.12.13;
- server 172.16.12.13 backup;
- }
目的服务器3配置:
- [root@localhost ~]#yum install -y httpd
- [root@localhost ~]#systemctl start httpd
- [root@localhost ~]#echo "welcome to server3" > /var/www/html/index.html
客户端测试:
当其他目的服务器都正常工作时,备份目的服务器不参与工作
当所有的目的服务器宕机(模拟关机)时,备份的目的服务器顶上
根据服务器的处理能力(权重)来分配请求,处理能力越高的服务器分配到的请求越多
在默认轮询的基础上增加权重,weight=number。如果后端有2个服务器其中一个配置权重为weight=3另外一个不配置默认是1,则有用户访问时分配给给有权重的服务器和不配置权重的服务器的比例为3:1
反向代理服务器配置:
- http {
- upstream web {
- server 172.16.12.12 weight=3;
- server 172.16.12.13;
- }
客户端测试:
最少连接调度算法,优先将客户端请求调度到当前连接最少的目的服务器,相当于LVS中的WLC。按照nginx反向代理服务器和目的服务器的连接数分配请求,连接越少的分配处理请求优先级越高。例如最小连接数(least_conn;) 是设置是3,目的服务器1 有2个请求在处理,而 目的服务器2 只有1个请求在处理,则新请求交给目的服务器2
反向代理服务器配置:
- http {
- upstream web {
- server 172.16.12.12 weight=3;
- server 172.16.12.13;
- least_conn;
- }
我们在访问网站的时候,进行登录以后,服务器上会生成一个session,然后服务器会携带着session_id返回给浏览器记录一个cookie值,当第二次访问时,cookie会来服务器上与session进行对比,如果对比成功,则不需要重新登录
基于客户端IP地址的负载均衡算法。它会根据客户端的IP地址,将该客户端的所有请求都发送到同一个目的服务器上。这样可以保证同一个客户端的所有请求都被发送到同一个目的服务器,从而保证了会话的一致性
反向代理服务器配置:
- http {
- upstream web {
- hash $remote_addr;
- server 172.16.12.12;
- server 172.16.12.13;
- }
客户端测试:
ip_hash算法的缺陷:
当新添加目的服务器3,那么之后请求资源的目的服务器会发生改变,不能保持会话连接
据请求的URL来进行负载均衡,负载均衡器会根据请求的URL计算哈希值,然后使用这个哈希值来确定将请求发送到哪一台服务器上,这种算法适用于对于同一个URL请求,希望每次都能被分发到同一台服务器上,比如对于一些需要保持会话一致性的场景
反向代理服务器配置:
- http {
- upstream web {
- hash $request_uri;
- server 172.16.12.12;
- server 172.16.12.13;
- }
客户端测试:
根据请求中的特定Cookie来进行负载均衡,负载均衡器会提取请求中的特定Cookie的数值,计算哈希值,然后使用这个哈希值来确定将请求发送到哪一台服务器上,这种算法适用于需要根据用户的会话信息来进行负载均衡的场景,比如在有状态的Web应用中,确保用户的会话信息始终被发送到同一台服务器
反向代理服务器配置:
- http {
- upstream web {
- hash $cookie_hello;
- server 172.16.12.12;
- server 172.16.12.13;
- }
客户端测试:
- http {
- upstream web {
- server 172.16.12.12;
- server 172.16.12.13 max_conns=10 max_fails=3 fail_timeout=30s;
- }
- #max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
- #max_fails=number 后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
- #fail_timeout=time 后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒。这样避免服务器刚上线不稳定再次导致业务失败
此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配
- http {
- upstream web {
- server 172.16.12.12 weight=3;
- server 172.16.12.13;
- fair; #实现响应时间短的优先分配
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。