在前篇关于《Nginx》的文章中曾经提到:单节点的Nginx
在经过调优后,可承载5W
左右的并发量,同时为确保Nginx
的高可用,在文中也结合了Keepalived
对其实现了程序宕机重启、主机下线从机顶替等功能。
但就算实现了高可用的
Nginx
依旧存在一个致命问题:如果项目的QPS
超出5W
,那么很有可能会导致Nginx
被流量打到宕机,然后根据配置的高可用规则,Keepalived
会对Nginx
重启,但重启后的Nginx
依旧无法承载业务带来的并发压力,结果同样会宕机.....
经过如上分析后,明显可看出,如果Nginx
面对这种超高并发的情况,就会一直处于「在重启、去重启的路上」这个过程不断徘徊,因此在此背景下,我们需要设计出一套能承载更大流量级别的接入层架构。
不过相对来说,至少
90%
以上的项目用不上这套接入层架构,因为大部分项目上线后,能够拥有的用户数是很有限的,压根无法产生太高的并发量,所以往往一个Nginx
足以支撑系统的访问压力。
不过虽说大家不一定用的上,但不懂两个字我们绝不能说出口,尤其是面试过程中,往往频繁问到的:你是如何处理高并发的? 跟本文有很大的联系,之后被问到时,千万先别回答什么缓存、削峰填谷、熔断限流、分库分表.....等这类的,首先需要先把接入层说清楚,因为如果接入层都扛不住访问压力,流量都无法进到系统,后续这一系列处理手段自然没有意义。
一、亿级吞吐第一战-DNS轮询解析
对于单节点的Nginx
而言,虽然利用Keepalived
实现了高可用,但它更类似于一种主从关系,从机在主机正常的情况下,并不能为主机分担访问压力,也就代表着作为主节点的机器,需要凭“一己之力”承载整个系统的所有流量。那么当系统流量超出承载极限后,很容易导致Nginx
宕机,所以也需要对Nginx
进行横向拓展,那又该如何实现呢?最简单的方式:DNS
轮询解析方案。DNS
轮询解析技术算一种较老的方案了,但在如今的大舞台上依旧能够看见它的身影,它源自于DNS
的域名多记录解析,在《HTTP/HTTPS》文章中曾聊到过,DNS
域名系统本质上是一个大型的分布式K-V
数据库,以域名作为Key
,以物理服务器的公网IP
作为Value
,而大多数域名注册商都支持为同一个域名配置多个对应的IP
,如下:
如上图所示,为一个域名配置多个映射的IP
后,DNS
服务器在解析域名请求时,就会依据配置的IP
顺序,将请求逐一分配到不同的IP
上,也就是《上文》所提及到的轮询调度方式。
借助
DNS
的轮询解析支持,对Nginx
可以轻松实现横向拓展,也就是同一个域名配置的多台物理机,分别都部署一个Nginx
节点,每台Nginx
节点的配置信息都一样。
好比目前每瞬12W
的并发量,配置域名时,映射3
台真实Nginx
服务器,最终经过DNS
轮询解析后,12W
的并发请求被均摊到每台Nginx
,每个节点分别承载4W
的并发请求,通过这种方式就能够完美的解决之前的:单节点Nginx
无法承载超高并发量而宕机的问题,如下:
![Nginx水平集群]
同时DNS
域名解析,也依旧可以配置调度算法,如Rate
权重分配、最少连接数分配、甚至可以按照客户端网络的运营商、客户端所在地区等方式进行解析分配,但仅一小部分的DNS
服务器支持。
浅谈DNS域名轮询解析的优劣
这种方式带来的优势极为明显:
无需增加额外的成本即可实现多节点水平集群,利于系统拓展。
但也存在非常大的劣势:
- ①与其他的负载均衡方案不同,其他的负载方案一般都会自带健康监测机制,但
DNS
则无法感知,也就是当下游的某服务器宕机,DNS
服务器会依旧向其分发请求。 - ②无法根据服务器的硬件配置,合理的分配客户端请求,大部分
DNS
服务器只支持最简单的轮询调度。
虽然DNS
轮询解析方案存在很大的劣势,但这两个劣势对比其带来的收益可以忽略不计,因为现在云计算技术的发展,多台节点保持相同的配置已不再是难事。同时,由于Nginx
本身就会利用Keepalived
的VIP
机制实现高可用,所以就算某个节点宕机,从机也可顶替上线接管流量,中间只会有很短暂的切换时间。
而且如果
DNS
将客户端请求分发到某个宕机节点时,客户端看到的结果便是空白页、超时无响应或请求错误的信息,通常情况下,依据用户的习性,都会再次重试,那么客户端再次发出的请求会被轮询解析到其他节点,而从机在这个时间间隔内也能够成功上线接管服务。