Nginx-基础篇-3【反向代理】
本文最后更新于 2023-09-19,文章内容可能已经过时。
反向代理
1.1. 基本概念
反向代理是一种网络技术,它可以将客户端的请求转发到后端服务器,并将响应返回给客户端。与正向代理不同,反向代理隐藏了后端服务器的身份,客户端只能看到反向代理服务器。反向代理可以用于负载均衡、安全性和缓存等方面。
正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。正向代理的情况下,客户端必须要进行一些特殊的设置才能使用。
不管是正向代理还是反向代理,本质代理服务器的带宽限制了网络传递数据的速度,有先天的局限性。
Nginx这种反向代理模式,也可以称作隧道式代理,为了解决上面说的局限性,如果能让我们后端的服务器,返回数据的时候,自己发送而不是经过代理服务器,就可以解决问题,这种模型就是DR
模型,可以使用类似nginx
的应用如 lvs
进行这样的操作,它本质上也算来连接内网的网关,只能向外面传数据,但是无法接受外面的请求。
1.2. 反向代理在企业中的应用
1.2.1. 传统公司架构
QPS是指每秒钟处理的请求数量,是衡量系统性能的重要指标之一。它可以用来评估一个服务器或网络设备的处理能力,通常用于衡量高并发系统的性能。QPS越高,说明系统每秒钟能够处理的请求数量越多,系统的性能也就越好。
Gataway Server 起到了统一管理后端服务器的网络请求,起到了鉴权作用,并非所有的请求都能访问后端的所有服务器,需要先经过网关服务器进行认证。
ERP是企业资源计划系统的缩写,是一种集成管理软件,旨在帮助企业管理和协调其各个部门的业务流程。它将各个部门的业务流程整合在一起,包括销售、采购、生产、库存、财务等,以提高企业的效率和生产力。ERP系统可以提供实时数据和分析,帮助企业做出更好的决策,并优化业务流程,减少重复工作和错误。
1.2.2. 中小型互联网公司架构
多台计算机干同样的事,多台服务器跑的都是一套完整的代码服务,这就叫集群,访问Nginx代理服务器,让它基于算法,如轮询,哈希等进行对集群的访问,达到最大化利用服务器资源的目的,这个功能就叫负载均衡。当然服务器看能不能访问的通肯定是访问才知道,所以当访问不同存在retry
重新向别的集群节点访问的能力。
1.3 反向代理实战
1.3.1 配置反向代理
反向代理也是配置在server的location下的,但是配置了反向代理,就不能配置root
和index
了。可以配置网址,主机,或者是主机群体。
同时如果不写前面的www.
会发现浏览器域名变成了跳转过去的域名,打开浏览器控制台能看到302
码【重定向】,说明进行了请求重定向。同时这里也不支持https
协议的代理,因为有了ca
证书,后续会深入讲解。这里我们可以改为其他服务器的ip,看看能否完成代理。
server {
listen 80;
server_name www.fanxy.cloud;
location / {
proxy_pass http://www.bilibili.com;
}
这里克隆两个虚拟机,并把配置换成最小化的默认配置,然后把他们默认index页面的样式改成对应主机名称方便辨认和做实验,然后把完成后续的代理学习。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
}
1.4. 基于反向代理的负载均衡
1.4.1. 轮询
这里类似RabbitMQ在联邦里学过的,上下流,定义一个上流对应的名称,这个层级和server是同一级别的。然后我们配置的反向代理域名填入上流定义的名称,即可完成最基本的负载均衡。【此时测试就是轮询访问,逐一转发,这种方式适用于无状态请求。】
upstream httptest {
server 192.168.110.103:80;
server 192.168.110.104:80;
}
# 虚拟主机 vhost
server {
listen 80;
server_name www.fanxy.cloud;
location / {
proxy_pass http://httptest;
# root /www/www;
# index index.html index.htm;
}
}
1.4.2. weight【权重】
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream httptest {
server 192.168.110.103:80 weight=10 backup;
server 192.168.110.104:80 down;
server 192.168.110.105:80 weight=2;
}
-
down
:表示当前的server暂时不参与负载 -
weight
:默认为1
.weight越大,负载的权重就越大。
-
backup
: 其它所有的非backup
机器down
或者忙的时候,请求backup
机器。
后面几种负载均衡的方式,几乎在企业中用不到这里只是保持知识的全面性来科普。ip_hash 在一些简单的、传统的架构里边还是有用的。工作环境中一般要么是使用基本的轮询和权重,只是会话一致性没法保证了,需要特别处理,而可以结合lua脚本去解决这个问题。后端的服务器一般轮询就无法保证有状态,常用的解决方案如SpringSession,就是利用把session统一放到一个服务器上,比如Redis服务器集群,每次访问的Sesion就不从对应的服务器找,而是先去Redis服务器上找。但这么做并不适合真正的高并发场景,高并发场景可以通过下放tocken的方式,比如每次访问服务器,会先经过权限校验服务器,客户端第一次登录的时候服务器给客户端办法一个令牌(token)会返回到客户端存储。后面所有的请求在请求头加上这个令牌去请求就可以了,tocken记录了当前会话的信息,且做了加密【非对称加密】,双方无法更改,或者说更改服务端校验就会失败。
补充
Session 是一种有状态的技术,浏览器中通过Cookie保持访问的状态,一个Session对应一个Cookie,Cookie保存了用户的SessionID,而服务器创建对应容器存放容器通过KV的Id找到对应的Session。有状态和无状态是指计算机系统的特性,有状态系统存储了关于用户或客户端的信息,以便在后续交互中使用。而无状态系统则不存储任何关于用户或客户端的信息,每个请求都是相互独立的。
在 Web 应用程序中,Session 技术通常用于跟踪用户的登录状态、购物车内容、偏好设置等信息。服务器会为每个用户分配一个唯一的 Session ID,并将其存储在服务器端。在用户与服务器进行交互时,服务器可以通过 Session ID 来识别用户,并访问存储在 Session 中的信息。
相比之下,无状态 Web 应用程序不存储任何关于用户的信息,每个请求都是相互独立的。因此,无状态应用程序通常需要在每个请求中包含足够的信息来标识用户和处理请求。这种方式可以提高系统的可伸缩性和可靠性,但也可能需要更多的网络带宽和处理能力。
1.4.3. ip_hash
根据客户端的ip地址转发同一台服务器,可以保持回话【Session】。现在因为移动端的存在,ip是经常变化的,所以这个策略就不太有意义了。
1.4.4. least_conn
最少连接访问,这个也不是特别合理,因为本身出现资源倾斜可能就是因为我们根据服务器的性能分配了不同权重,这么设置就导致又拉回均衡访问。同时我们动态扩容一台服务器上下线,我们设置了最少连接访问也是不支持的。因为上了一台新机器要重新reload配置文件,会导致服务暂时中断,之前说过其实会开新的进程,原先进程如果有后端服务会让它继续完成再关闭,如果没关闭可能是耗时的服务,或者是延迟服务,比如15分钟的交易时间。一般后端会进行异步化处理,可以比如放入rabbitmq的延迟队列,以异步方式进行使用。此时大家几乎都归零了,使用这个策略并不会达到我们预期想要完成的平衡。
1.4.5. url_hash
需要专门下载第三方插件,根据用户访问的url定向转发请求,可以完成定向流量转发,本质也是为了解决会话一致性问题,由于 url_hash 的哈希冲突问题,可能会导致请求被错误地分配给错误的服务器,或者缓存响应时出现数据丢失或混淆的情况。此外,url_hash 只能存储有限的信息,并且不是唯一的,因此在某些情况下可能不够灵活。因此,在使用 url_hash 之前,需要仔细考虑其局限性,并确定它是否适合特定的应用场景。
1.4.6. fair
需要专门下载第三方插件,根据后端服务器响应时间转发请求。这个也不合理,因为实际情况下响应时间是动态变化的, 可能本身设置好访问策略,有一台性能好的服务器它只是因为交换机过热,导致访问它的速度变慢,使用这个策略导致访问集中分给了其他性能差的,形成了流量倾斜的风险,甚至可能出现突然压垮这些服务器的可能。
- 感谢你赐予我前进的力量