要说清楚什么是反向代理,我们就需要先从最简单的C/S架构说起,C/S架构,也即是Client-Server的架构。而最简单的C/S架构,也即是以单个节点作为后端Server的C/S架构。
C/S架构中的单点Server
在普通的开发当中,单点Server的服务方式非常常见,比如使用Django框架做后台服务的时候,就可以通过简单的run server命令运行起一个临时的服务,接着通过地址就可以访问到这个服务了。当然了,对于Django而言,run server命令只是提供开发周期的调试使用的便捷工具,更一般的情况是通过uWSGI把这个Django服务跑起来,以获取并比run server更好的服务性能。
此时部署整一个架构图如下:
对于请求量非常少的服务,这样的部署不会有什么问题,但如果这个服务请求量上来的时候,这样部署的架构就很有问题了。
首先一个很客观的问题就是,如果单从服务器的物理特性来看,这个服务器就不能支持这么高的请求量。这种情况下,就迫使开发者去把服务迁移到一个CPU更强、内存更高,综合性能更好的服务器。通过更换服务器当然可以解决这个问题,在不考虑成本的条件下,总可以找到性能更好的服务器来替换原来的服务器以支撑服务,但这种理想的条件不在本文考虑范围之内。
第二个问题就是,如果服务Server单节点发生了故障,就必然会影响整个服务,因为对于众多的Client客户端都是连接的一个Server服务端,如果这个节点不可用了,势必会影响所有使用了客户端的用户。
为了解决这两个显而易见的问题,就必须提出一种可以横向拓展的部署架构,使得服务可以支撑的请求量可以随着服务的横向拓展而增加。因而就催生了如下的部署架构:
基于代理的可横向拓展的C/S架构
在这个部署的架构当中,除了Server节点,还多出了一个叫“Proxy”的节点,那么这个节点是干嘛的呢?
“Proxy”的这个节点,它把他接收的所有的请求都转发到他后面的Server节点当中,然后等待Server节点处理请求,再从Server节点取回执行结果返回到Client。所以“Proxy”的这个节点,他实际上不处理任何的请求。
我们先来看这样子的架构怎么解决了以上的问题,再来思考“Proxy”的这个角色。
首先是第一个问题,服务器性能不足的问题,这个架构如何解决性能不足的问题呢?在这个架构里面,假设Server节点S1性能到达瓶颈了,不能处理更多的请求了。如果采用上面的这个架构,那么我们可以添加Server节点S2,同时告诉“Proxy”节点,让他把部分原来转发到S1节点的请求转发到我这里来。这样子通过服务分流减少压力的方法就可以解决原来S1节点性能不足的问题了。
接着是第二个问题,单点服务器挂掉了怎么办。还是考虑Server节点S1和S2,两者所能够提供的服务是一样的,假设某一个时候S1挂掉了,这时如果有“Proxy”节点的存在,并且“Proxy”节点能够察觉到S1挂掉了的话,那么让“Proxy”节点把原来要转发给S1节点的请求转发到S2进行处理就可以了,这样子通过服务冗余的方法就可以解决原来S1突然挂掉影响服务的问题。
解决了这两个问题,接下来我们再从这两个问题里面“Proxy”的角色来理解,什么叫做代理。
在第一个问题里面,“Proxy”节点通过服务分流的方法来减少S1的压力,对于原来应该被S1服务的,却由于被“Proxy”节点转发而被S2服务的Client而言,Client他并不知道实际上是由S1处理的还是S2处理的,Client拿到的是一个从“Proxy”节点返回的结果,换言之,Client并不知道自己的请求实际上是被哪个处理的,他只需要往“Proxy”节点发送请求就好了,剩下的工作就由“Proxy”节点去解决。
也就是,“Proxy”节点相当于一个中介,或者说是一个代理,代理Client去寻找实际的Server节点去完成服务。这样子的模式在现实生活也非常常见,在买房子的时候,通常由房产中介帮助你完成和卖者之间的手续,而不需要你亲自去处理这些事情,你只需要协调好自己与中介之间的手续就好了,这里的中介,就和我们的“Proxy”节点所做的工作非常类似。
同样的,在第二个问题里面,也是相似的理解方式,Client并不需要感知S1是否还能正常工作,Client只需要把请求发送给“Proxy”节点,由它去帮忙处理就可以了。
因此,这里面的“Proxy”节点,也就是我们的代理节点。
正向代理与反向代理
理解了什么是“代理”,离我们理解什么是“反向代理”就只差“反向”两个字了,与“反向”相对的,就是“正向”,本质上来讲,代理都是存在于Client和Server之间,但是由于性质不同,所以也分为这两种。在这一个部分,我们将会学习,什么是反向代理,什么是正向代理。
直观的以两个例子去理解什么是正向代理和反向代理。假设由A、B和C三人,他们之间存在借钱的关系。
对于正向代理,理解起来就是:
- A需要钱,A知道C由很多钱,想向C借钱
- 但是A和C有矛盾,于是A想到通过B去借C借钱
- B向C借到钱了,C不知道是A的存在
- 这样B就帮助A借到了Z的钱
在这个过程,B就充当了代理借钱的角色,并且是代替A去借钱的,这样就是正向代理。
接着是反向代理:
- A需要钱,C有很多钱,A不知道C很多钱
- A找B借钱
- B知道C有很多钱
- B向C借钱,并把借到的钱给A,而没有使用自己的钱借给A
- A拿到钱以后,以为钱是B的,A不知道C的存在
在这个过程当中,B也充当了代理借钱的角色,不过这次不是代替A去借的,而是用C的钱借给A的,换言之即是代替C将钱借给了A,这就是反向代理。
- 在例子里面,把A换成Client,把C换成Server,就是计算机的例子了。
两者区别
- 服务对象不同
- 正向代理,代理的是客户端,也就是例子中的A,服务端不知道实际发起请求的客户端
- 反向代理,代理的是服务端,也就是例子中的C,客户端不知道实际提供服务的服务端
正向代理
反向代理
2. 安全模型不同
- 正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此必须采取安全措施以确保仅为授权的客户端提供服务
- 反向代理都对外都是透明的,访问者并不知道自己访问的是代理,访问者不知道服务节点的存在,认为处理请求的就是代理节点
总而言之,正向代理是从客户端的角度出发,服务于局域网用户,以访问非特定的服务,其中最典型的例子就是翻墙;反向代理正好与此相反,从服务端的角度出发,服务于所有用户,隐藏实际的服务节点,服务节点的架构对用户透明,以代理节点统一对外服务。