当前位置: 首页 > 编程日记 > 正文

亿级PV请求的三种负载均衡技术

在互联网+不断渗透到生活中的今天,各种各样的网络服务存在在我们身边,他们的访问流量也是大得惊人。一个大型网站(百万PV以上)想要正常访问,单单靠一台服务器是不可能提供稳定服务的。这时候就需要用负载均衡技术将海量的接口请求平均分发到各个服务器上,以减少每台服务器的压力。

595137-20170411110659813-918315312.png

上面的流程图展示了从用户请求和响应的整个路程。用户按下一个按钮,一个请求通过网络转发到运营商网络,运营商对其进行DNS解析。如果请求所对应的域名配置了DNS轮询,那么运营商将会随机返回域名对应的一个服务器IP,之后将请求转发到该服务器上。当请求到达服务器时,首先会达到LVS虚拟服务器,虚拟服务器再根据具体算法转发给后边的Nginx服务器。当Nginx接收到请求时,Nginx服务器会根据其配置将请求再次转发给其后端配置的应用服务器,应用服务器才是最终处理业务请求的地方。

在整个请求过程中,有三种负载均衡技术:第一次是DNS轮询,第二次是LVS负载均衡,第三次是Nginx负载均衡

DNS轮询

DNS轮询指的是服务提供者在运营商针对某一域名配置了多个提供服务的服务器IP,当用户请求改域名的接口时,运营商将随机挑选出一个服务器响应用户请求。下图的例子是:有3台联通服务器、3台电信服务器,要实现“联通用户流量分摊到3台联通服务器、其他用户流量分摊到电信服务器”这个效果的设置。

595137-20170411110710094-1372998016.png

DNS由于成本较低,所以一般在小型的网站用的比较多。但是大型的网站一般也会将用它和其他负载均衡的方式结合起来一起使用,DNS轮询方式提供的IP地址,在大型网站中往往是一个集群的地址,可能是均衡交换机也可能是均衡服务器。我们可以通过nslookup命令来查询域名的DNS配置情况:

C:\Users\Administrator>nslookup www.baidu.com
服务器:  UnKnown
Address:  10.10.121.11非权威应答:
名称:    www.a.shifen.com
Addresses:  58.217.200.11358.217.200.112
Aliases:  www.baidu.com

DNS轮询的优点是成本低、操作简单,但是其缺点也是明显的:

  • 服务不稳定。如果某台服务器宕机,DNS服务器是无法知晓的,仍旧会将访问分配到此服务器。修改DNS记录全部生效一般要1-3小时,甚至更久。这就可能会导致某些用户在服务器发生故障的时候完全无法访问。
  • DNS负载均衡采用的是简单的轮询算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能较好的服务器多分配请求,甚至会出现客户请求集中在某一台服务器上的情况。
  • 登陆状态无法保存。如果是需要身份验证的网站,DNS解析无法将验证用户的访问持久分配到同一服务器。虽然有一定的本地DNS缓存,但是很难保证在用户访问期间,本地DNS不过期,而重新查询服务器并指向了新的服务器,那么原服务器保存的用户信息是无法被带到新服务器的,而且可能被要求重新认证身份,而且来回切换时间长了各台服务器都保存有用户不同的信息,对服务器资源也是一种浪费。

正是因为上述存在的缺点,所以DNS一般不会单独使用,而是配合其他负载均衡方式一起使用。

LVS负载均衡

LVS服务器接收到网络请求后,会根据配置的算法将请求转发给后边的服务器处理。为了实现高可用,一般情况下都会有至少两台LVS服务器,它们之间用KeepAlive定时通信。当备用LVS服务器无法接收到主LVS服务器的信息时,备用LVS服务器就认为主LVS已经宕机了,这时候备用LVS将自动切换为主LVS提供服务。

使用LVS架设的服务器集群系统有三个部分组成:最前端的负载均衡层(Loader Balancer),中间的服务器群组层,用Server Array表示,最底层的数据共享存储层,用Shared Storage表示。在用户看来所有的应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。LVS的体系架构如图:

595137-20170411110724251-1336692307.jpg

LVS的各个层次的详细介绍:

  • Load Balancer层:位于整个集群系统的最前端,有一台或者多台负载调度器(Director Server)组成,LVS模块就安装在Director Server上,而Director的主要作用类似于一个路由器,它含有完成LVS功能所设定的路由表,通过这些路由表把用户的请求分发给Server Array层的应用服务器(Real Server)上。同时,在Director Server上还要安装对Real Server服务的监控模块Ldirectord,此模块用于监测各个Real Server服务的健康状况。在Real Server不可用时把它从LVS路由表中剔除,恢复时重新加入。

  • Server Array层:由一组实际运行应用服务的机器组成,Real Server可以是WEB服务器、MAIL服务器、FTP服务器、DNS服务器、视频服务器中的一个或者多个,每个Real Server之间通过高速的LAN或分布在各地的WAN相连接。在实际的应用中,Director Server也可以同时兼任Real Server的角色。

  • Shared Storage层:是为所有Real Server提供共享存储空间和内容一致性的存储区域,在物理上,一般有磁盘阵列设备组成,为了提供内容的一致性,一般可以通过NFS网络文件系统共享数 据,但是NFS在繁忙的业务系统中,性能并不是很好,此时可以采用集群文件系统,例如Red hat的GFS文件系统,oracle提供的OCFS2文件系统等。
    从整个LVS结构可以看出,Director Server是整个LVS的核心,目前,用于Director Server的操作系统只能是Linux和FreeBSD,linux2.6内核不用任何设置就可以支持LVS功能,而FreeBSD作为 Director Server的应用还不是很多,性能也不是很好。对于Real Server,几乎可以是所有的系统平台,Linux、windows、Solaris、AIX、BSD系列都能很好的支持。

LVS 的IP负载均衡技术是通过IPVS模块来实现的,IPVS是LVS集群系统的核心软件,它的主要作用是:安装在Director Server上,同时在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问服务。这个虚拟IP一般称为LVS的VIP,即Virtual IP。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取一个服务节点响应用户的请求。

当用户的请求到达负载调度器后,调度器如何将请求发送到提供服务的Real Server节点,而Real Server节点如何返回数据给用户,是IPVS实现的重点技术,IPVS实现负载均衡机制有三种:DR模式、NAT模式、Full-NAT模式、Tunnel模式,其中DR模式是使用最广泛的一种。

DR模式

595137-20170411110734563-1537827671.png

特点:工作在数据链路层,由LVS修改请求报文的Mac地址,由RS服务器直接返回响应给客户端。

  • 用户按下按钮,发送接口请求,此时网络数据包关键信息为:【源IP:client_ip,目标IP:lvs_ip,Mac地址:lvs_mac_address】
  • 当用户请求到达LVS服务器的时候,LVS服务器直接将改网络数据包的Mac地址修改为RS服务器的Mac地址,之后将其转发到RS服务器。此时网络数据包关键信息为:【源IP:client_ip,目标IP:lvs_ip,Mac地址:rs_mac_address】
  • 当RS服务器接收到网络数据包时,RS服务器发现请求报文的Mac地址是自己的地址,就接收报文并进行处理。处理完成之后,将响应报文通过网卡向外发出。此时发出的响应报文数据包关键信息为:【源IP:lvs_ip,目标IP:client_ip,Mac地址:rs_mac_address】
  • 响应报文最终到达客户端

这种方式是三种负载调度机制中性能最高最好的,但是必须要求Director Server与Real Server都有一块网卡连在同一物理网段上。

NAT模式

595137-20170411110743001-242197446.png

特点:工作在网络层,由LVS修改请求报文的目标IP地址以及响应报文的源IP地址,必须经LVS返回给客户端。

  • 用户按下按钮,发送接口请求,此时网络数据包关键信息为:【源IP:client_ip,目标IP:lvs_ip,Mac地址:lvs_mac_address】
  • 当用户请求到达LVS服务器的时候,LVS服务器直接将改网络数据包的目标IP地址修改为RS服务器的IP地址(DNAT技术),之后将其转发到RS服务器。此时网络数据包关键信息为:【源IP:client_ip,目标IP:rs_ip,Mac地址:lvs_mac_address】(这里有一个问题,为什么Mac地址是lvs_mac_address,但数据包就能够到RS服务器呢?)
  • 当RS服务器接收到数据包后对比发现目标IP是自己的IP,于是构建响应报文发送给LVS服务器。此时网络数据包关键信息为:【源IP:rs_ip,目标IP:client_ip,Mac地址:client_mac_address】
  • LVS服务器接收到响应报文,修改响应报文的源IP地址为LVS的IP地址,然后响应给客户端。此时发出的响应报文数据包关键信息为:【源IP:lvs_ip,目标IP:client_ip,Mac地址:client_mac_address】
  • 响应报文最终到达客户端

NAT模式要求LVS和RS服务器必须在同一网段内,因此会导致运维上的困难。另外因为每次请求都需要经过LVS服务器,所以LVS服务器的压力会比较大。

Full-NAT模式

595137-20170411110756172-2017859529.png

特点:工作在网络层,在LVS修改请求报文以及响应报文的源IP地址、目标IP地址,必须经LVS返回给客户端。

  • 用户按下按钮,发送接口请求。此时网络数据包关键信息为:【源IP:client_ip,目标IP:lvs_ip,Mac地址:lvs_mac_address】
  • 当用户请求到达LVS服务器的时候,LVS服务器直接将改网络数据包的源目标IP地址修改为LVS服务器的IP地址、目标IP地址修改为RS服务器的IP地址(SNAT技术、DNAT技术),之后将其转发到RS服务器。此时网络数据包关键信息为:【源IP:lvs_ip,目标IP:rs_ip,Mac地址:lvs_mac_address】
  • RS服务器接收到数据包,于是构建响应返回给LVS服务器。此时网络数据包关键信息为:【源IP:rs_ip,目标IP:lvs_ip】
  • 当LVS收到RS服务器的响应数据包后,LVS服务器直接将改网络数据包的源目标IP地址修改为LVS服务器的IP地址、目标IP地址修改为客户端的IP地址(SNAT技术、DNAT技术)。此时网络数据包关键信息为:【源IP:lvs_ip,目标IP:client_ip】
  • 响应报文最终到达客户端

Full-NAT模式是在NAT基础上为了解决跨子网问题而诞生的,其通过在网络层修改源IP地址和目标IP地址来达到不同子网的通信。

Tunnel模式

特点:工作在网络层,在原有IP报文外多封装一层IP报文,由RS服务器直接返回响应给客户端。

  • 用户按下按钮,发送接口请求。此时网络数据包关键信息为:【源IP:client_ip,目标IP:lvs_ip】
  • 当用户请求到达LVS服务器的时候,LVS服务器直接在原有报文外再次封装一层IP报文,封装的源IP地址为lvs_ip,目标IP地址为rs_ip,然后将其转发到RS服务器。此时网络数据包关键信息为:外部报文-->【源IP:lvs_ip,目标IP:rs_ip】,内部报文-->【源IP:client_ip,目标IP:lvs_ip】。
  • RS服务器接收到报文后发现时自己的IP地址,就将报文接收下来。拆除掉最外层的IP报文后,会发现里面还有一层IP报文,而且目标是lvs_ip,那么此时RS开始处理此请求,处理完成之后,直接将响应报文发送给客户端。此时网络数据包关键信息为:【源IP:lvs_ip,目标IP:client_ip】
  • 响应报文最终到达客户端。
工作模式所处OSI层级模式特点缺陷
DR模式数据链路层由LVS修改请求报文的Mac地址,由RS服务器直接返回响应给客户端LVS服务器和RS服务器必须要在同一级房
NAT模式网络层由LVS修改请求报文的目标IP地址以及响应报文的源IP地址,必须经LVS返回给客户端LVS和RS服务器必须在同一网段内
Full-NAT模式网络层在LVS修改请求报文以及响应报文的源IP地址、目标IP地址,必须经LVS返回给客户端-
Tunnel模式网络层在原有IP报文外多封装一层IP报文,由RS服务器直接返回响应给客户端-

其实与LVS相似的流量转发方案还有HAProxy。LVS与HAProxy都适合用来放在负载均衡的最前端,用于海量流量转发。在高可用支持上,他们都有对应的高可用方案,LVS与KeepAlive结合实现高可用,而HAProxy与heartbeat实现高可用。在配置难度上,LVS配置比较复杂,而HAProxy相对简单。在系统支持上,Linux系统对LVS有内核级别的支持,而HAProxy则没有。在性能上,LVS因为有系统内核级别的支持,所以其可以实现响应数据包不经过LVS,而HAProxy的响应数据包则必须经过HAProxy,这就导致了HAProxy的压力会比较大,也就是HAProxy性能没有LVS好。

Nginx负载均衡

当请求经过LVS服务器转发到达Nginx服务器后,Nginx会根据其负载配置文件将请求转发到具体的应用服务器进行处理。

与Nginx相似的软件还有apche、squid、lighttpd等负载均衡软件,但apache和squid属于同步模式的反向代理,在大文件的传输上会出现阻塞,导致后端服务器连接数过多,最终导致服务器压力过大。而Nginx和lighttpd则是使用异步模式的反向代理,代理在接受完数据之前不会与后端服务器建立连接,这样就避免了对后端服务器造成过大压力。

举个例子:当用户上传一个100M大的文件时,如果用户网速慢,需要半个小时才能上传完。如果采用apache、squid这种同步模式的反向代理,那么在接收过程中代理不仅会与客户端建立连接,还会有后台服务器建立连接。如果上传大文件的用户一多,那么后端服务器的压力就很大。而且因为广域网(WAN)和局域网(LAN)的传输速度差别很大,因此同步方式的反向代理会造成连接资源的浪费。而nginx和lighttpd异步模式的反向代理则是等代理完全接收完数据之后,才与后端服务器建立连接,这样就大大减少了后端的服务器的压力。

而nginx和lighttpd的异步模式也略有不同,lighttpd是先收完再转向客户浏览器,而nginx是边收数据边转向用户浏览器。因此nginx的异步代理模型可以更好地提供高性能的负载均衡,所以现在nginx也是许多企业级网站的首选。

软件名称代理特性工作细节
apache、squid同步模式在与客户端连接的同时,也与后端的服务器建立连接
lighttpd异步模式等待客户端传输完成才与后端服务器建立连接,同时不会返回数据给客户端
nginx异步模式等待客户端传输完成才与后端服务器建立连接,同时会返回数据给客户端

LVS 与 Nginx 的区别

既然LVS和Nginx都能实现负载均衡,那为什么要将Nginx作为LVS后端机器,而不是LVS作为Nginx的后端机器,他们之间到底有什么区别呢?

LVS设计就是用来进行流量转发的,功能比较单一,所以其在流量转发上性能更高、更稳定。LVS在流量转发的性能基本达到了F5硬件设备的60%性能,其他几个10%都有点困难。但也正是因为其效率高、稳定,所以导致了其功能单一,在应用场景方面比较单一。而Nginx功能强大,支持对域名、目录的解析,这使得其应用场景广泛。

简单地说:lvs只做简单转发,能做的事情也就很少,nginx功能全面,能满足很多的业务场景。

所以我们才说LVS更加适合做最前端的流量转发,挡住海量流量。而Nginx则适合放在应用服务器的上层,用来针对不同的请求进行目录识别或域名识别,从而达到功能模块的垂直分割。

参考资料

  • Web基础架构:负载均衡和LVS - 李克华 - 博客园
  • squid,nginx,lighttpd反向代理的区别 - TroyHector - 博客园
  • lvs与haproxy

相关文章:

The Six Best Practices(1~3)

前几期的图文我们介绍了软件工程中常见的问题,分析了产生这些问题的根本原因,引出了软件工程中的六个最佳经验。今天我们具体介绍这些最佳经验的内容。

Java项目命名规范

2019独角兽企业重金招聘Python工程师标准>>> 一、命名规范 1、 项目名全部小写 2、 包名全部小写 3、 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写。 如:public class MyFirstClass{} 4、 变量名、方法名首字…

一道数据结构算法题

现有一个链表,证明如果存在环,则:使用两个指针同时前进但步长不一样,则能够在有限步之后能够相逢。题目的意思是我归纳出来的,我的解题思路是这样的:能够相下逢的意思是:在走了x步以后&#xff…

win7系统下载 ghost win7 Sp1 32位纯净3月版

win7系统下载 ghost win7 Sp1 32位纯净3月版软件名称: Ghost Win7 Sp1 32位纯净3月版软件语言: 简体中文软件大小: 3.81大小: GB发布日期: 2017-03-21文件名称: ZJY_Ghost_win 7_X86_CJ201703.GHOM D 5: C21A7A17D8C2568A05844C5…

The Six Best Practices(4~6)

昨天图文介绍了The Six Best Practices的前三个经验:迭代化开发、需求管理、基于构件的体系构架,今天介绍后面的三个经验:可视化建模、持续的质量验证和变更管理。

代码生成器前戏 之 数据库元数据

总结:代码生成器大致有两种方式,1.根据po 生成 表 结构 等系列类,如 Hibernate自动生成 2.根据表生成 po 等系列类。其实实际 开发时候 多半还是 先设计好表,然后生成 的情况多。 元数据:描述数据的数据,就…

有感于框架设计难,实施框架更难!

很久没有写了,不能怪没有时间,只是自己太懒。这两天休息,有时间重新回顾一下项目的设计,从目前的开发情况看,最早设计的一些编程框架,并没有很好的遵守,看上去比较零乱,这个可能由于…

六个最佳的软件工程实践(基于构件的体系结构、可视化建模)

昨天图文介绍了迭代化开发和需求管理,今天我们介绍基于构件的体系结构和可视化建模。基于构件的体系结构是软件开发中最体现创造力的地方,可以通过“修建桥梁”来理解为什么要贯彻基于构件的体系结构以指导我们每次开发的演进增量过程。可视化建模是为了…

通讯组基本管理任务一

经常收发邮件的人都有同感:很多时候都需要向一组人发送邮件。如果一封封地发送,不仅耽误时间,而且很容易出错,将邮件发送给不应该接受邮件的收件人。Exchange Server 2010为了方便用户使用,通过“通讯组”和“地址列表…

无人驾驶相关数据集

普林斯顿大学人工智能自动驾驶汽车项目: 代码V1:http://deepdriving.cs.princeton.edu/DeepDrivingCode_v1.zip 代码V2: http://deepdriving.cs.princeton.edu/DeepDrivingCode_v2.zip 训练集(50G):http://…

六个最佳的软件工程实践(持续的质量验证、变更管理)

昨天图文介绍了基于构件的体系结构以及可视化建模,今天我们介绍六个最佳工程实践的最后两个,持续的质量验证以及变更管理。持续的质量验证是伴随迭代化开发而进行的不断验证,且每次迭代的测试集合都是不断递增的。质量验证不仅从功能方面要满…

css层叠样式表(一)

今天研究了下css。这东东入门不算难。可是想写出好的样式就得有很深的功底了。按照老大给网址,12天学会网页设计。做下总结吧。css通过div(层)来定位,通过层的margin,padding,border等属性来控制板块的间距。常用的模型是盒状模型…

aspx页面使用ajax遇到try catch中使用Response.End()报错

1、使用Ajax接收数据,在返回Response.Write()后应该调用Response.End()才能将数据写入到调用的页面,才能被jQuery的回调函数获取到返回的JSON数据 2、在try--catch里面不能用Response.End(),否则会报错:由于代码已经过优化或者本机框架位于调…

GO是更好的编程语言吗?

引言 团队有项目考虑用GO重写,所以花了些时间调研GO。 第一次接触GO是2年前,17年3月份,全职钻研一周,彼时C中毒太深,内心排斥其他编程语言,看其他语法总觉得有点怪,而且有“C/C能做任何事&#…

定位DIV滚动条

如果由于table中有一个下拉框,还有一个treeview时,treeview的所有节点都是取于下拉框的下拉选项来的,所以在第一定位这之后,当选择其他下拉框中其他的选项时,DIV的scrollTop值是会一直保存前一个步聚DIV滚动条所在的位…

JS作用域相关知识(#精)

在学习《你不知道的JS》一书中,特将作用域相关知识在此分享一下: #说到作用域,就不得不提到LHS查询和RHS查询: 1)如果查询目的是对变量进行赋值,则使用LHS查询 2)如果查询目的是获取变量的值,则使用RHS查询 作用域的查询都会从当前…

RUP within the context of the Six Best Practices

前面几期图文介绍了软件工程中常见的问题,以及找到它们的根本原因,提出了在软件工程实践中总结出来的六个最佳工程实践。迭代化开发、需求管理、基于构件的体系结构、可视化建模、持续的质量验证、变更管理。今天我们介绍Rational公司的RUP,看…

排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎不大相同,不知是因为java的缘故还是因为我算法的缘故,欢迎拍砖。 复习排序&#xf…

项目存档管理规范

项目存档管理规范 在我们开发过很多个项目之后,每个项目都会累积下很多源码、文档等,查找和整理起来很不方便,如果我们又要同时工作于多个项目的话,情况会更糟。所以对每个项目的各种档案进行有效管理很有必要,从公司层…

review what i studied `date` - 2017-4-12

python 连接字符串 int srt >>> a 1 >>> b xuhui >>> a b Traceback (most recent call last):File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for : int and str >>> b str(a)…

StaticFactoryMethod_Level1

以下代码是“简单工厂模式”的第一个例子&#xff1a;

逃离深圳,一个程序员的选择

到新公司上班也已经一个多月了&#xff0c;上周刚刚交了首付&#xff0c;总价50多万&#xff0c;97个平方的房子还外送8个平方。为了不忘记这次的选择&#xff0c;也为了记录这次选择的过程&#xff0c;特撰文如下。 自从得知老婆怀孕后&#xff0c;那是相当高兴&#xff0c;但…

弹出窗口(对话框)

对话框分为三种&#xff1a;window.open方法 无模式对话框 有模式对话框 第一&#xff1a;OPEN方法 <script>functionopen_cate(){ window.open("OpenUp.aspx","","toolbar0,location0,directories0,status0, menubar0,scr…

隐藏系统保留区

为了下午的装机活动自己就安了一个老毛桃&#xff0c;制作启动盘完毕后发现电脑中的“系统保留”盘出来了&#xff0c;为什么会出现这个盘呢&#xff1f; 当笔记本安装Windows7系统时会自己主动产生一个几百兆的系统保留分区。里面保存着系统/磁盘引导的数据。有些笔记本在出厂…

StaticFactoryMethod_Level2

以下代码是“简单工厂模式”的第二个例子&#xff1a;

06- web兼容性测试

稍后更新。。转载于:https://www.cnblogs.com/Chamberlain/p/11064664.html

話說我們家姚明

已經讀三年級了,成績不錯,有目共睹!最近三場比賽連續三次得分在30分以上...呵呵~在NBA那個高手如雲的地方如此出色! ^_^#好強~ 真的好強!!麥迪那個軟蛋,干脆把他賣掉得了!拿高工資不做事的人.. 凸-_-转载于:https://www.cnblogs.com/tohen/archive/2006/03/09/346286.html

20145240《网络对抗》MSF基础应用

MSF基础应用 一个主动攻击&#xff0c;如ms08_067 启动msfsearch ms08_067&#xff0c;查找相应的漏洞&#xff0c;查询可攻击的模块。根据上述漏洞的模块use exploit/windows/smb/ms08_067_netapi选择该模块接下来查看相应的攻击载荷&#xff0c;首先我们可以查看可使用的载荷…

StaticFactoryMethod_Level3

以下代码是“简单工厂模式”的第三个例子&#xff1a;

Dynamics CRM 导入用户数据错误 could not retrieve salesperson role

在CRM中通过导入数据的方式创建用户时报下图中的错误&#xff0c;“could not retrieve saleperson role”。原因是系统中的自带的salesperson安全角色被删除了&#xff0c;在用导入数据的方式导入文档新建用户时是没有安全角色让你选择的&#xff0c;系统默认给分派了销售员的…