2.1.3 反向代理
在进一步了解 NGINX 前,我们先来了解一个概念:“反向代理”。
所谓的“代理”,通常是指“代理服务器”,它是位于客户端和服务端之间的一类中间服务器。当代理存在时,客户端的请求会首先到达代理服务器,代理服务器将此请求拦截后,转而向源服务器发出请求。在得到源服务器的响应后,代理服务器再响应客户端。但是,这个过程显然会降低通信速度,增加故障的概率,那么,我们为什么还要这样做?引入代理有哪些好处呢?
解决源服务器的负载问题
当服务的请求量较少,服务器压力不高时,单个源服务器就可以满足要求。当服务请求量上升,服务器的压力过高时,我们首先想到的可能是提高服务器的性能,但是单个服务器的性能提升总是很有限的,请求量持续增长,要不了多久,一台拥有高级配置的服务器也会不堪重负。这时,一个自然的想法就是,增加服务器的数量,使用多台服务器分摊压力。
客户端使用域名请求服务器时,首先会通过DNS查询,得到服务器的IP地址,进而才能和服务器建立TCP连接,随后发起HTTP请求。
当源服务器只有一台时,我们只需要给域名添加一条DNS记录,配置源服务器的IP地址即可。
当源服务器增加至多台时,每个服务器往往都具有独立的IP地址,此时要解决的一个问题,就是一个域名如何与多台服务器联系起来,也就是我们常说的“负载均衡(Load Balance)”。在这种情形下,负载均衡是指将网络请求分摊到多个不同服务器的技术。
隐藏客户端或服务端
当客户端和源服务器直接通信时,双方都能知道对方的真实IP地址,当代理服务器存在时,客户端或服务器的真实IP就可以被隐藏。隐藏源服务器IP,可以减少针对源服务器的网络攻击,隐藏客户端IP,可以更好地保护个人隐私。
代理服务器可以位于客户端侧或者服务端侧。客户端侧的代理服务器通常由客户自行设置,比如在操作系统中添加的VPN(Virtual private network,虚拟专用网络)连接,网络游戏加速器等。这类代理代替客户端与服务器进行通信,由于它们的存在,服务端便无法获得客户端的真实IP地址。有时也称这类代理为“正向代理”。
服务端侧的代理服务器通常由网站运维人员设置,这类代理代替最终的源服务器与客户端进行通信,进而隐藏了源服务器。这些代理被称为“反向代理”。因为无法获知源服务器的IP,网络攻击者只能针对反向代理服务器进行攻击。原本分散到各个源服务器的攻击,此时集中到代理服务器上,所以代理服务器的安全防护至关重要。
我们在实际使用Web服务时,正向代理和反向代理是可以同时存在的。
代理服务器的缓存
代理服务器可以将HTTP响应进行缓存,当某个请求的响应被代理服务器缓存,下次相同的请求到达,代理服务器就可以直接响应,而不必再向源服务器发出请求。
显然,不合理的缓存可能导致服务异常,HTTP1.0 中引入 Expires 和 Last-Modified 等标头,实现了缓存控制。HTTP 1.1 引入了 Cache-control,Vary,Etag 等进一步完善了缓存控制机制。
Cache-control 标头设置为 public 时,即表明服务端允许公共缓存(如代理服务器)保存此响应。而当 Cache-control 标头设置为 private 时,代理服务器不被允许缓存响应。
API网关的本质,就是一个反向代理。利用NGINX,我们可以很轻松地实现反向代理功能,示例如下。
方便起见,server 块指令外地配置项已被省略。
通过使用 proxy_pass 指令,可以将 /hello 请求代理到 http://10.2.10.1/hello。10.2.10.1 是一个A类的私有IP地址,它指向的是一台局域网的服务器。
使用上述配置的NGINX服务器,当接收到 /hello 请求时,它会向 http://10.2.10.1/hello 再发起 HTTP 请求,当 http://10.2.10.1/hello 响应后,NGINX再将响应传回客户端。此时,NGINX就起到了反向代理服务器的职能。
proxy_pass
proxy_pass URL;
设置代理服务器的协议、地址,以及转发到的URL。
现实中,源服务器往往不止一台,譬如,有四台服务器( 10.2.10.1 - 10.2.10.4)可以提供服务,此时怎样办呢?
对于这种情况,我们通常采用“服务器组”的方式进行配置。通过 upstream 模块,我们可以定义一组服务器,而这组服务器的组名,就可以用在 proxy_pass 指令中。
upstream
upstream name { ... }
设置代理服务器的协议、地址,以及转发到的URL。
重新加载最新的配置后,到达NGINX的 /hello 请求会被均匀地分配到四台源服务器上。如此,我们就实现了一个具有负载均衡功能的反向代理服务器。
NGINX的功能是如此强大,以至于我们了解到这里,就已经完成了一个API网关的核心。
参考文章:https://www.nginx.com/c/deploy-nginx-as-an-api-gateway/ 参考文章:https://www.nginx.com/resources/videos/10-tips-for-deploying-nginx-as-an-api-gateway/
Last updated