- 原文地址(本人博客):www.waylon.online/blog?id=769…
简介
Nginx 是一个高性能网络服务器,旨在满足现代网络日益增长的需求。它专注于高性能、高并发和低资源使用。尽管它通常被称为 Web 服务器,但 Nginx 的核心是一个反向代理 服务器,也正是因Nginx 的反向代理设计,可以轻松地将其配置为负载均衡器。
反向代理
在上文中,我说到了Nginx中一个非常重要的一个概念:反向代理;
在介绍反向代理之前我们先了解下代理的概念:所谓代理(Proxy),便是一种使客户端无需直接连接到目标服务器而间接访问该服务器的网络服务。它充当了客户端与目标服务器之间的中介,接收来自客户端的请求并将其转发到目标服务器,然后将响应返回给客户端,而代理又可根据特性分为正向代理与反向代理;
正向代理(Forward Proxy)
是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。
作用:
-
突破访问限制:通过代理服务器,可以突破自身ip访问限制比如VPN,或者前端领域中我们在使用webpack、vite进行本地开发时,调用接口会显示跨域,需要配置devSever代理对应的接口地址;
-
提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,会将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度;
-
隐藏客户端真实ip:上网者可以通过正向代理的方法隐藏自己的ip,免受攻击;
反向代理(Reverse Proxy)
是介于目标服务器与客户端之间的代理服务器,代表目标服务器向客户端发送响应。在这种情况下,客户端不知道目标服务器的存在,只知道反向代理服务器的存在。反向代理常见的用途包括实现负载均衡、提供安全性和简化请求处理等。
作用:
- 隐藏服务器真实ip:使用反向代理,可以对客户端隐藏服务器的ip地址;
- 负载均衡:反向代理服务器可以做负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上;
- 提高访问速度:反向代理服务器可以对静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度;
- 提供安全保障:反向代理服务器可以作为应用层防火墙,为网站提供对基于web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等;
在Nginx中,配置反向代理非常简单,主要通过proxy_pass指令实现,如下
server {
listen 80;
server_name localhost;
location / {
root dist;
try_files $uri $uri/ /index.html;
}
# 在80端口中匹配以/mobile/开头的请求,将其代理到8080端口中
location ^~ /mobile/ {
proxy_pass http://127.0.0.1:8080/;
}
# 在80端口中匹配以/api/开头的请求,将其代理到3000端口中
location ^~ /api/ {
proxy_pass http://127.0.0.1:3000/;
}
}
负载均衡
有了反向代理的存在,我们可以知道实际应用中客户端与服务端是一个多对多的关系,这种多对多的关系很有可能会导致其中某一台服务器负载过大的问题;
对于此类问题,我们通常采取3种措施:
- 横向扩展:增加服务器数量,将请求分散到多台服务器上处理,从而减轻单一服务器的压力。
- 纵向扩展:升级服务器硬件配置,如增加 CPU、内存等,提高服务器的性能,从而提高服务器的容量和吞吐量。
- 负载均衡:通过负载均衡技术,将请求分发到多个服务器上,从而平衡服务器的负载。
很显然,前两种措施都伴随着一定的经济开销,所以我们首先考虑的一定是负载均衡,通过负载均衡去均衡分工,控制流量,避免出现局部节点负载过大的问题。通俗的讲,就是如何为每台服务器合理的分配请求,使其整体具有更高的工作效率和资源利用率。
为什么前面会有较多的篇幅去介绍反向代理,实际上负载均衡就是通过反向代理,将客户端发送过来的请求,合理的代理到对应的服务器中。
Nginx实现负载均衡
在Nginx中,主要通过upstream模块实现负载均衡,它的作用是将请求转发给多个后端服务器,并根据不同的算法进行负载均衡,Nginx自带的负载均衡策略包括:轮询、权重、ip_hash,让我们分别介绍它们的实现;
轮询
轮询分配是最简单的负载均衡策略,无需其他配置,Nginx会按照次序将请求分配给每个服务器,具体实现如下;
upstream waylon { # 这个名字可以随便起,但是要尽量符合服务器的用途和域名
server 192.168.0.101:3000;
server 192.168.0.102:3000;
}
http {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://waylon/; # 代理到对应的upstream
}
}
}
特点:由于该算法中每个请求按时间顺序逐一分配到不同的服务器处理,因此适用于服务器性能相近的集群情况,其中每个服务器承载相同的负载。但对于服务器性能不同的集群而言,该算法容易引发资源分配不合理等问题。
权重
为了解决上述的服务器性能不一的问题,我们引入了权重分配,具体实现如下:
upstream waylon {
# # 192.168.0.101的访问比率要比192.168.0.102的访问比率高一倍
server 192.168.0.101:3000 weight=2;
server 192.168.0.102:3000 weight=1;
}
http {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://waylon/; # 代理到对应的upstream
}
}
}
特点:加权轮询可以应用于服务器性能不等的集群中,使资源分配更加合理化。
ip_hash
在实际场景中,为了实现会话保持和避免操作冲突的问题,Nginx还为我们准备了一套ip_hash的策略,让同一个客户端的请求总是被转发到同一个后端服务器上,具体实现如下:
upstream waylon {
ip_hash; # 加上这个命令即可
server 192.168.0.101:3000;
server 192.168.0.102:3000;
}
http {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://waylon/; # 代理到对应的upstream
}
}
}
特点:可以保证同一个IP地址的请求始终被转发到同一个后端服务器上,因此能够有效地解决会话保持和操作冲突的问题。这种方式用于解决集群部署环境下 Session 不共享的问题。
补充
除了以上3种Nginx自带的策略,我们还可以使用一些第三方策略,比如:URL_hash、最小连接数策略,这里不过多做介绍。
同时Nginx的upstream模块还支持一些高级功能,如健康检查、动态添加和删除后端服务器等,这里也不过多做介绍,剩余的内容可自行在Nginx官网查阅~
参考文档
Nginx官网 - 负载均衡器: www.nginx-cn.net/products/ng…