一个没有负载均衡的 web 架构类似下面这样:
在这里用户是直连到 web 服务器,如果这个服务器宕机了,那么用户自然也就没办法访问了。另外,如果同时有很多用户试图访问服务器,超过了其能处理的极限,就会出现加载速度缓慢或根本无法连接的情况。
而通过在后端引入一个负载均衡器和至少一个额外的 web 服务器,可以缓解这个故障。通常情况下,所有的后端服务器会保证提供相同的内容,以便用户无论哪个服务器响应,都能收到一致的内容。
从图里可以看到,用户访问负载均衡器,再由负载均衡器将请求转发给后端服务器。在这种情况下,单点故障现在转移到负载均衡器上了。这里又可以通过引入第二个负载均衡器来缓解,但在讨论之前,我们先探讨下负载均衡器的工作方式。
负载均衡器可以处理什么样的请求?
负载均衡器的管理员能主要为下面四种主要类型的请求设置转发规则:
-
HTTP
-
HTTPS
-
TCP
-
UDP
负载均衡器如何选择要转发的后端服务器?
负载均衡器一般根据两个因素来决定要将请求转发到哪个服务器。首先,确保所选择的服务器能够对请求做出响应,然后根据预先配置的规则从健康服务器池(healthy pool)中进行选择。
因为,负载均衡器应当只选择能正常做出响应的后端服务器,因此就需要有一种判断后端服务器是否「健康」的方法。为了监视后台服务器的运行状况,运行状态检查服务会定期尝试使用转发规则定义的协议和端口去连接后端服务器。如果,服务器无法通过健康检查,就会从池中剔除,保证流量不会被转发到该服务器,直到其再次通过健康检查为止。
负载均衡算法
负载均衡算法决定了后端的哪些健康服务器会被选中。几个常用的算法:
-
Round Robin(轮询):为第一个请求选择列表中的第一个服务器,然后按顺序向下移动列表直到结尾,然后循环。
-
Least Connections(最小连接):优先选择连接数最少的服务器,在普遍会话较长的情况下推荐使用。
-
Source:根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。
如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器。可以通过 Source 算法基于客户端的 IP 信息创建关联,或者使用粘性会话(sticky sessions)。
最后,想要解决负载均衡器的单点故障问题,可以将第二个负载均衡器连接到第一个上,从而形成一个集群。
当主负载均衡器发生了故障,就需要将用户请求转到第二个负载均衡器。因为 DNS 更改通常会较长的时间才能生效,因此需要能灵活解决 IP 地址重新映射的方法,比如浮动 IP(floating IP)。这样域名可以保持和相同的 IP 相关联,而 IP 本身则能在服务器之间移动。
常用的负载均衡:
-
硬件负载均衡 常见的硬件有比较昂贵的F5和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用。
-
软件负载均衡 目前使用最广泛的三种负载均衡软件Nginx/LVS/HAProxy,他们都是基于Linux的开源免费的负载均衡软件,这些都是通过软件级别来实现,所以费用非常低廉。
-
成熟的架构 成熟的架构有LVS+Keepalived、Nginx+Keepalived、HAProxy+keepalived。 二、 优缺点分析
-
Nginx的优点是: 1.1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,Nginx单凭这点可利用的场合就远多于LVS了。 1.2、Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反LVS对网络稳定性依赖比较大; 1.3、Nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。LVS的配置、测试就要花比较长的时间了,LVS对网络依赖比较大。 1.4、可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS相对小些。 1.5、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。 1.6、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。 1.7、Nginx现在作为Web反向加速缓存越来越成熟了,速度比传统的Squid服务器更快,可以考虑用其作为反向代理加速器。 1.8、Nginx可作为中层反向代理使用,这一层面Nginx基本上无对手,唯一可以对比Nginx的就只有lighttpd了,不过lighttpd目前还没有做到Nginx完全的功能,配置也不那么清晰易读,社区资料也远远没Nginx活跃。 1.9、Nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有Nginx社区非常活跃,第三方模块也很多。
-
Nginx的缺点是: 2.1、Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点。 2.2、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。不支持Session的直接保持,但能通过ip_hash来解决。 2.3、LVS:使用Linux内核集群实现一个高性能、高可用的负载均衡服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。
-
Nginx常用四种算法: 3.1、rr:轮叫,轮流分配到后端服务器; 3.2、wrr:权重轮叫,根据后端服务器负载情况来分配; 3.3、lc:最小连接,分配已建立连接最少的服务器上; 3.4、wlc:权重最小连接,根据后端服务器处理能力来分配。
-
LVS的优点是: 4.1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和cpu资源消耗比较低。 4.2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。 4.3、工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如LVS+Keepalived,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived。 4.4、无流量,LVS只分发请求,而流量并不从它本身出去,这点保证了均衡器IO的性能不会收到大流量的影响。 4.5、应用范围比较广,因为LVS工作在4层,所以它几乎可以对所有应用做负载均衡,包括http、数据库、在线聊天室等等。
-
LVS的缺点是: 5.1、软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。 5.2、如果是网站应用比较庞大的话,LVS/DR+Keepalived实施起来就比较复杂了,特别后面有Windows Server的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。
-
Nginx常用四种算法: 6.1.roundrobin:轮询,轮流分配到后端服务器; 6.2.static-rr:根据后端服务器性能分配; 6.3.leastconn:最小连接者优先处理; 6.4.source:根据请求源IP,与Nginx的IP_Hash类似。
-
HAProxy的特点是: 7.1、HAProxy也是支持虚拟主机的。 7.2、HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,Cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态。 7.3、HAProxy跟LVS类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。 7.4、HAProxy支持TCP协议的负载均衡转发,可以对MySQL读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,大家可以用LVS+Keepalived对MySQL主从做负载均衡。 7.5、HAProxy负载均衡策略非常多,HAProxy的负载均衡算法现在具体有如下8种: ① roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的; ② static-rr,表示根据权重,建议关注; ③ leastconn,表示最少连接者先处理,建议关注; ④ source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注; ⑤ ri,表示根据请求的URI; ⑥ rl_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name; ⑦ hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求; ⑧ rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。 三、 Nginx和LVS对比的总结: 1、Nginx工作在网络的7层,所以它可以针对http应用本身来做分流策略,比如针对域名、目录结构等,相比之下LVS并不具备这样的功能,所以Nginx单凭这点可利用的场合就远多于LVS了;但Nginx有用的这些功能使其可调整度要高于LVS,所以经常要去触碰触碰,触碰多了,人为出问题的几率也就会大。 2、Nginx对网络稳定性的依赖较小,理论上只要ping得通,网页访问正常,Nginx就能连得通,这是Nginx的一大优势!Nginx同时还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线路;LVS就比较依赖于网络环境,目前来看服务器在同一网段内并且LVS使用direct方式分流,效果较能得到保证。另外注意,LVS需要向托管商至少申请多一个ip来做Visual IP,貌似是不能用本身的IP来做VIP的。要做好LVS管理员,确实得跟进学习很多有关网络通信方面的知识,就不再是一个HTTP那么简单了。 3、Nginx安装和配置比较简单,测试起来也很方便,因为它基本能把错误用日志打印出来。LVS的安装和配置、测试就要花比较长的时间了;LVS对网络依赖比较大,很多时候不能配置成功都是因为网络问题而不是配置问题,出了问题要解决也相应的会麻烦得多。 4、Nginx也同样能承受很高负载且稳定,但负载度和稳定度差LVS还有几个等级:Nginx处理所有流量所以受限于机器IO和配置;本身的bug也还是难以避免的。 5、Nginx可以检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。目前LVS中 ldirectd也能支持针对服务器内部的情况来监控,但LVS的原理使其不能重发请求。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而恼火。 6、Nginx对请求的异步处理可以帮助节点服务器减轻负载,假如使用apache直接对外服务,那么出现很多的窄带链接时apache服务器将会占用大量内存而不能释放,使用多一个Nginx做apache代理的话,这些窄带链接会被Nginx挡住,apache上就不会堆积过多的请求,这样就减少了相当多的资源占用。这点使用squid也有相同的作用,即使squid本身配置为不缓存,对apache还是有很大帮助的。 7、Nginx能支持http、https和email(email的功能比较少用),LVS所支持的应用在这点上会比Nginx更多。在使用上,一般最前端所采取的策略应是LVS,也就是DNS的指向应为LVS均衡器,LVS的优点令它非常适合做这个任务。重要的ip地址,最好交由LVS托管,比如数据库的 ip、webservice服务器的ip等等,这些ip地址随着时间推移,使用面会越来越大,如果更换ip则故障会接踵而至。所以将这些重要ip交给 LVS托管是最为稳妥的,这样做的唯一缺点是需要的VIP数量会比较多。Nginx可作为LVS节点机器使用,一是可以利用Nginx的功能,二是可以利用Nginx的性能。当然这一层面也可以直接使用squid,squid的功能方面就比Nginx弱不少了,性能上也有所逊色于Nginx。Nginx也可作为中层代理使用,这一层面Nginx基本上无对手,唯一可以撼动Nginx的就只有lighttpd了,不过lighttpd目前还没有能做到 Nginx完全的功能,配置也不那么清晰易读。另外,中层代理的IP也是重要的,所以中层代理也拥有一个VIP和LVS是最完美的方案了。具体的应用还得具体分析,如果是比较小的网站(日PV小于1000万),用Nginx就完全可以了,如果机器也不少,可以用DNS轮询,LVS所耗费的机器还是比较多的;大型网站或者重要的服务,机器不发愁的时候,要多多考虑利用LVS。 四、现在对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术: