当前位置: 首页 > 科技观察

Windows平台分布式架构实践-负载均衡

时间:2023-03-11 20:46:43 科技观察

概述最近,.NET的世界开始动荡了。微软官方加入了对.NET跨平台的支持,在不久的将来,我们在VS中编写的代码可能可以通过Mono直接运行在Linux和Mac上。那么为什么大家(开发者和企业)如此热切希望。NET跨平台?第一个原因是便宜。淘宝声称有超过40,000台服务器都运行在Linux上。Linux平台下也有免费的MySql。有什么损失,为什么不做呢?第二个原因是Linux系统下还有很多优秀的框架(当然也是免费的),分布式缓存Memcached,大数据处理框架Hadoop等,对一些大型分布式系统提供了很好的支持。支持,当然,比如Liniux系统本身的一些安全和网络优势等等。所以难怪大佬们都同意不选择.NET。但是如果。NET也支持跨平台,那么这种模式可能就要改变了。以上所有优点依然可以保留,并且凭借其语法的优越性和快速的开发效率,依然会为它争得一席之地。但是,在Windows平台下实现这些大规模的分布式系统是不是就不可能了呢?我敢肯定这个问题已经被广泛讨论过,但至少我还没有看到更清晰、更完整的案例。带着这些疑问,我决定升级自己的机器,自始至终在windows平台下搭建一个高度可扩展的分布式网站。本人还是新手,很多东西还在摸索阶段,如有错误还望指点。什么是负载均衡?负载均衡可以帮助我们解决两个问题。首先是提高可用性。这里的可用性主要是从WEB服务器的角度。如果我们只有一台Web服务器,它遇到了一些未知的错误导致IIS无法启动,那么我们的网站就无法访问了。这是一个相对较低的可用性。然后使用负载均衡,放在我们的web服务器前面,它会收集所有的请求,转发给我们的web服务器。这时候我们可以添加两台web服务器。如果其中一个坏了,至少还有另一个在工作,不会导致我们的网络无法访问。当然,有人可能会问,负载均衡器坏了怎么办?那不是仍然无法访问网站吗?我们这里讨论的是提高可用性。为了实现365天*24小时的不间断服务,需要额外的组件来支持。我们稍后再讨论。除了可用性,负载均衡还可以帮助我们提高可扩展性。当然,这种可扩展性也指的是Web服务器级别。从网站性能的角度来看,几个程序员花了好几天时间做了一些优化,有时带来的效果可能还不如直接加个记忆棒那么快。加内存没关系,我们还是可以换个更好的CPU。换掉CPU后,我们仍然可以使用固态硬盘,甚至很多公司已经开始直接将数据存储在内存中(注:具体场景具体情况具体对待)。如果这些都不能添加怎么办?让我们添加更多机器。一台服务器可以处理1000个并发,那么两台服务器理论上就是2000个,所以这就是我们的横向扩展。负责平衡器分发的请求类型。所有请求首先到达负载均衡器,然后转发到特定的Web服务器。转发方式分为以下几种:Round-robin:最简单的方式,这种方式基本上不能算是负载均衡。第一个请求是web1,下一个是web2,再下一个是web3……不会考虑是不是某个服务器负载过大等等。基于权重的分配(Weight-based):可以配置每台服务器处理请求数据的比例,特别适用于某台服务器配置不同的场景。比如某台服务器配置特别好,那么我们就可以让它处理更多的请求。随机(Random):随机分配。粘性会话(StickySession):负载均衡器会跟踪请求,确保具有相同会话ID的请求被投递到同一台服务器。Leastcurrentrequest:将最新的请求转发给当前处理请求数最少的服务器。响应时间优先级(Responsetime):当前响应时间最短的服务器将被分配给该服务器。UserorURLparameterselection(UserorURLinformation):一些负载均衡器也会提供一些参数来决定处理哪个服务器,比如用户信息,地址位置,URL参数,cookie信息等。我们还可以根据负载均衡器使用的技术将它们分为以下几类:反向代理:负载均衡器作为代理,同时维护两个TCP请求,接收来自客户端的请求,然后转发请求到相应的Web服务器返回Response时,返回给代理服务器,再由代理服务器转发给真正的客户端。这样会导致一些功能不可用,比如在WEB服务器环境下查看请求的源IP,实际上变成了我们代理服务器的IP等。透明反向代理:和上面的代理服务器一样,只是获取到的信息WEB服务器从Request传来的是真正的客户端信息,就好像没有使用代理一样。服务器直接返回:通过改变WEB服务器的MAC地址实现分发请求。这样WEB服务器就不会像上面那样使用代理服务器了。请求处理完成后,会直接返回给客户端。都相对于反向代理而言,这种方式的性能会更快。NAT负载均衡:NAT(NetworkAddressTranslation),将网络包(可以理解为TCP包)中的目标IP地址转换为需要处理请求的WEB服务器地址。MicrosoftNetworkLoadBalancing:Windows自带的负载均衡组件,一会儿我们会用它来测试。没有负载均衡的测试结果。一个独立的服务器。我们可以从网站的初始版本开始。一开始,我们决定做一个网站,但不知道效果如何。Lightkey在那个时候,我们很穷,所以我们租了一台托管主机,它可能至少承担三个或更多的角色:WEB服务器,静态资源服务器,数据库服务器。我们可以用ASP.NETMVC4+SQL2008做一个基本的电商网站,基本够用了。但是它能承载多少流量呢?下面来做个简单的测试(注:本文之后的系列测试都是在虚拟机上进行的,忽略网络因素和多台虚拟机同时运行时的CPU资源因素,所以测试结果仅供参考)。我的机器上有一个虚拟机配置如下:CPU:IntelCoreI5-4570,3.19GHz,Memory:4GHardDisk:20G(ShineDiskSSD)测试页面没有复杂的逻辑,使用ASP.NETMVC4+Entityframework6.0+SQL2008+IIS8.5实现,我们的页面只是一个简单的列表页面,列出了系统中所有的产品。HomeController代码 Index.cshtml代码在数据库初始化时插入500条测试数据连接字符串,然后使用本地连接。我们使用轻量级ab做压力测试,如果你对ab不熟悉的可以点这里,下面是测试结果:ab-n1000-c100http://192.168.1.131通过测试发现我们单台服务器的吞吐率接近110~130,并且一旦并发数达到200后,每个请求的处理时间达到1.5s以上。400个并发用户时,每个请求耗时3s以上。在真实的网络环境中可能更糟。由此,我们可以得出结论,我们的服务器最多可以支持大约120个同时访问。#p#WEB服务器和数据库服务器分离下面我们来做一个扩容,成本不高,有空间,不需要改动任何架构,只需要增加一个专用的数据库服务器即可。再来看看测试结果:可以看到,这里我们的吞吐率(每秒处理请求数增加到150左右),并发处理能力增加了50%,响应时间在300而且400并发速度也比上面的schema要好。使用负载均衡的测试结果安装NetworkLoadBalancing(NLB),我们独立的web服务器和独立的数据库服务器的组合已经可以处理大约150个并发。现在让我们想象一下,如果网站的知名度越来越高。越大,400个用户同时来访问怎么办?从上图我们可以看到在并发400个的情况下服务器的处理时间是2582.637ms(实际中这个是得到响应的时间,因为我们是同一台机器上的不同虚拟机,并且我是在host.test上做的,所以我们忽略网络传输时间,假设这是我们的服务器处理时间),这个服务器响应时间也是我们通过F12->network看到的等待时间。当页面能得到这个响应时,必须加上网络传输时间,即Receiving。1ms的传输时间太惊人了!我家的长城宽带10M早上总是出奇的好,晚上就挂了,可能你们现在都不在博客园了:)用户体验的黄金法则之一:网站加载时间=用户体验,别说3S了,你可能等2S你的页面还没出来,用户就要走了。以下是淘宝购物车页面的加载时间。国内很多大型网站的响应时间基本都控制在100ms以内,基本达到那种一输入地址一回车,眨眼就出来的页面。当然,这不是光有一个负载均衡器,加几台Web服务器就可以解决的。后面我们会一步步练习。话虽如此,上面的测试结果基本上只能说明并发为10时响应时间在100ms以内,看来我们还有很长的路要走。正所谓“最好的架构是演化出来的,而不是设计出来的”,面对我们目前的瓶颈,我们可以通过负载均衡的方式临时添加多个web服务器。上面我们讲到负载均衡器的类型的时候,有一种微软的负载均衡器,我们可以很方便的通过服务器管理器将这些组件安装到我们的服务器中。安装我们就不说了,进入服务器管理->添加角色和功能->在功能中选择“网络负载均衡器”,然后安装即可。注意:图中的Loadbalancer其实并不存在,因为只要在我们两台web服务器上安装网络负载均衡组件,就可以在其中任意一台上建立集群。图片是为了方便大家。在这种情况下,我们的服务器架构会是这样的:192.168.1.254是我们对外暴露的IP地址,访问192.168.1.254的请求会被转发到下面两台WEB服务器。#p#配置网络负载均衡我们为以上两台WEB服务器安装好NLB后,我们在其中任意一台上新建一个集群,然后将另外一台添加到这个集群中。我们在web-01(192.168.1.130)中创建这个集群。在搭建集群之前,我们需要确保两台服务器使用的是静态IP,否则无法加入集群。在web-01(192.168.1.130)上从管理工具打开网络负载均衡器右击“网络负载均衡集群”,选择“新建集群”在“新建集群:连接”窗口添加192.168.1.130作为主机,点击下一步进入“新建集群:主机参数”,直接进入“新建集群:集群IP地址”,在窗口中添加“添加”,在窗口中添加192.168.1.254点击下一步进入“新建集群:集群参数”,选择“Multicast”点击Next进入“NewCluster:PortRules”,全选,然后点击Edit修改端口范围为80~80,协议选择“TCP”,依赖选择“None”,单击OK返回主窗口并单击Finish。通过以上步骤,我们已经建立了一个集群,并将web-01添加到集群中。我们还需要手动将web-02添加到集群中。右键单击集群(192.168.1.254)和“将主机添加到集群”。在“AddHosttoCluster:Connection”窗口中,在host中输入192.168.1.131,然后点击Next。现在我们可以到我们的真机上去访问192.168.1.254,也就是说我们马上就进入测试环节了。#p#测试结果本文所有测试结果不取第一个结果,EF也需要预热。同样的查询也缓存在EF中,所以第一次的结果会和后面的测试结果有很大的区别,后面几次(相同参数下)基本区别不大。可以看到现在我们的吞吐率平均在230左右。与WEB服务器+DB服务器相比,处理能力提升了50%。为什么不是100%?一个web服务器可以处理150个并发,那么两者应该是300吧?我能想到的原因有以下几点:我们只有一台数据库服务器,数据库的处理能力无法提升,最终会影响到WEB服务器的处理能力。我们使用虚拟机,而不是实际机器。他们实际上共享CPU。不知道在这种情况下,会不会影响测试结果(有虚拟化高手可以分享)。为了验证,我又扩展了一个WEB服务器,我们用3个WEB服务器+1个DB服务器看看效果如何。让我们创建一个新的虚拟机web-03并将其也添加到我们的集群中。测试开始!加入第三台WEB服务器后,我们的吞吐率(每秒处理请求数)从230提升到360,并发处理能力提升了56%。每个请求的处理时间在1s以内,恭喜!最后两张图让你更直观的看到这些性能变化:以上数据是在我自己的机器上测试的,所有虚拟机都使用与第一台服务器相同的配置。总结在网站架构的不断演进中,负载均衡扮演着非常重要的角色。它不仅为我们提高了可靠性和可扩展性,还与一些比较强大的硬件设备一起提供了缓存和会话机制。我们今天使用的负载均衡是WindowsServer自带的一个组件。是最简单的实现负载均衡的方式,但是功能不是特别完善,而且一旦NLB自身出现错误,所有网站都将无法访问。让我们通过引入APR(ApplicationRequestRouter)来解决这个问题。您想真正了解大型网站的架构,而不仅仅是了解负载均衡、分布式缓存和数据库分离吗?那就来跟我学吧!另外,我们今天只是用一个简单的页面做了压力测试,只有读数据操作,没有写操作,也没有复杂的事务,不过别着急,一步步来吧:)。原文链接:http://www.cnblogs.com/jesse2013/p/dlws-loadbalancer.html