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

Windows平台分布式架构实践 - 负载均衡概述
最近.NET的世界开始闹腾了微软官方终于加入到了对.NET跨平台的支持并且在不久的将来我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行。那么大家开发者和企业为什么那么的迫切的希望.NET跨平台呢第一个理由是便宜淘宝号称4万多台服务器全部运行在LinuxLinux平台下还有免费的MySql,这些都是免费的这些省下来直接就是利润呀做企业的成本可以降低又没有任何损失何乐而不为呢第二个理由是在Linux系统下还有很多非常优秀的构架当然同样也是免费的分布式缓存Memcached, 大数据处理构架Hadoop等等这些都为一些大型的分布式系统提供了很好的支撑当然还有诸如Liniux系统本身的一些安全和网络方面的优势等等。 所以也难怪大佬们都纷纷不约而同的没有选择.NET。但是如果.NET也支持跨平台之后那这样的格局可能就要发生变化了。上面所有的优势依然可以保留并且加上它语法的优越性以及快速的开发效率等还是会为其争得一席之地的。但是是不是Windows平台下就不能实现这些大型的分布式系统呢我相信这个问题已经被广泛讨论过但是至少我没有看到比较清晰的完整的案例。带着这些问题我决定升级我的机器自己从头到尾在windows平台下搭建一个高可扩展性的分布式网站出来。我经验尚浅很多的东西还处于摸索阶段所以如果有错误还请大师多多指点。您还可以查看本篇的续篇: Windows平台下利用APM来做负载均衡方案 - 解决Session同步问题以及彻底提高可用性。什么是负载均衡负载均衡可以帮我们解决两个方面的问题第一个即提高可用性。这里面的可用性主要是从WEB服务器的角度来讲的如果说我们只有一台Web服务器而它遇到了某种未知的错误导致IIS无法启动那么我们的网站就无法访问了这就是一种比较低的可用性。那么利用负载均衡放在我们Web服务器的前面由它来收集所有的请求然后转发给我们的Web服务器 这时候我们就可以添加两台Web服务器如果其中有一台坏了至少还有另一台在工作也不至于导致我们的网络无法访问。当然有人可能会问如果那台Load balancer坏了怎么办那不是还是访问不了网站么我们这里讨论的是提高可用性在做到365天*24小时不间断的服务需要有另外的组件来支撑我们留在后面讨论。除了可用性以外负载均衡还可以帮助我们提高可扩展性当然这个可扩展性同样是指的Web服务器层面。从网站性能的角度来讲好几个程序员花上好几天的时间做了一些优化所带来的效果有时候可能还没有直接加一根内存条来的快。内存加完了没什么影响我们还可以换更好的CPUCPU换完了我们还可以用固态硬盘甚至很多公司已经开始直接把数据放到内存中了注具体场景具体对待。 如果这些都不可以再加了呢那就再加机器吧一台服务器可以处理1000个并发那么两台理论上是2000了所以这就有了我们的横向扩展。负责均衡器分发请求的类型所有的请求首先全部到达Load balancer再由它转发到具体的Web服务器转发的方式分为以下几种轮转调度(Round-robin):最简单的方式这种方式基本上不能算是负载均衡。第一个请求给web1下一个给web2再下一个给web3... 不会考虑某 一个服务器是不是负荷太重等等。基于权重的分配(Weight-based): 可以配置每一台服务器处理请求数据的比例特别适合那种有某台服务器配置不一样的场景。比如说某台服务器配置特别好那我们可以让它多处理一些请求。随机Random): 随机分配。粘性sessionSticky Session): Load balancer会跟踪请求确保同一个session id的请求都交给同一样服务器。最空闲优先Least current request将最新的请求转发给当前处理请求数量最小的那个服务器。响应时间优先(Response time)哪台服务器当前响应时间最短就给哪台。用户或URL参数选择(User or URL information)部分负载均衡器还提供根据一些参数来决定哪台服务器来处理比如说根据用户信息地址位置URL参数cookie信息等 。我们还可以根据负载均衡器所使用的技术将它们分为以下几类反向代理负载均衡器作为一个代理同时维持着两个TCP请求从客户端接收请求然后将请求转发给相应的Web 服务器,等Web返回Response的时候是返回给了代理服务器然后再由代理服务器转交给真正的客户端。这样就会导致有一些功能不可用比如在WEB服务器环境查看请求的来源IP实际上成了我们代理服务器的IP等。透明反向代理和上面的代理服务器一样只不过WEB服务器从Request中获取到的信息是真正客户端的信息就是好像没有使用代理一样的。直接服务器返回通过更改WEB服务器的MAC 地址来实现分发请求在这种方式下WEB服务器不会像上面使用代理服务器一样请求处理完之后是直接返回给客户端的所有相对于反向代理来说这种方式的性能会更快一些。NAT 负载均衡NAT(Network Address Translation网络地址转换)将网络包可以理解成TCP包中的目标IP地址变成实现要处理这个请求的WEB服务器的地址。Microsoft 网络负载均衡Windows 自带的负载均衡组件一会我们就用它来做测试。不使用负载均衡的测试结果一台独立的服务器我们可以从一个网站的最初级版本开始说起最开始的时候我们决定搭建一个网站但是我们也不知道效果会怎么样光键是那时候我们很穷于是我们租用了一台托管主机它可能承担了至少三个或以上的角色WEB服务器、静态资源服务器以及数据库服务器。我们可以用ASP.NET MVC4 SQL 2008来做一个基本的电子商务网站基本够用了。但是能够承载多大的访问量呢下面我们来做一个简单的测试注意本文以后本系列所面所有的测试都是在虚拟机上进行的忽略网络的因素以及多台虚拟机同时运行时CPU资源的因素所以测试结果只是一个参考。在我的机器上有一台虚拟机配置如下CPU: Intel Core I5- 4570, 3.19GHz,内存: 4G硬盘20G (ShineDisk 固态硬盘)测试页面没有什么复杂的逻辑利用ASP.NET MVC4 Entityframework 6.0 SQL 2008 IIS8.5来实现 我们的页面也只是一个简单的列表页列出系统里面所有的商品。Home Controller 代码Index.cshtml 代码在数据库初始化的时候插入500条测试数据连接字符串就使用本地连接就可以了。123connectionStringsadd nameCarolContextconnectionStringServerlocalhost;databasecarol;trusted_connectiontrueproviderNameSystem.Data.SqlClient//connectionStrings我们使用的轻量级的ab来做压力测试如果不熟悉ab的可以点这里下面是测试的结果ab -n1000 -c100 http://192.168.1.131通过测试发现我们这单个服务器的吞吐率接近在110~130之间而一旦并发数达到200以后每个请求的处理时间就达到1.5s多了400个并发用户的时候每个请求要花上3s多的时间。如果在真实的网络环境中可能会更差。由此我们可以得出我们这个服务器可能最大支持120人左右同时访问。WEB服务器与数据库服务器分离现在我们来做一个花费不是很大又空间做的扩展也不需要改任何架构我们只是再加一台专门的数据库服务器。下面我们再来看一下测试结果大家可以看到这里我们的吞吐率(每秒处理请求数已经提升到了150左右)并发处理能力提升了50%并且300和400并发的时候响应时间也比上面的架构要好一些。使用负载均衡的测试结果安装网络负载均衡NLB)上面我们一台独立的Web服务器和一台独立的数据库服务器的组合已经可以处理150左右的并发了现在我们假想一下如果网站的的知名度越来越大如果同时有400个用户来访问怎么办 从上面的图中我们可以看到400个并发的时候服务器的处理时间为2582.637ms实现上这是拿到响应的时间因为我们是一台机器上的不同虚拟机我是在主机上做测试所以我们就忽略网络传输的时间假设这个就是我们的服务器处理时间这个服务器响应时间也就是我们通过F12-网络 中看到的等待时间 。页面什么时候能拿到这个响应还要加上网络传输的时间也就是Receiving。1ms的传输时间堪称神速啊我家用的长城宽带10M总是早上网络出奇的好一到晚上就挂掉了还有可能就是你们现在都没有上博客园 :)用户体验黄金法则之一: 网站加载时间 用户体验别说3S可能等个2S你页面还不出来用户准备离开了下面是淘宝购物车页面的加载时间 。国内很多大型的网站的响应时间基本上都控制在100ms以内基本达到那种一输入地址敲回车眨眼之间页面就出来了。当然这并不是光有个负载均衡加几台web服务器就能解决的我们后来再来一步一步的实践下去。 话说回来我们上面的测试结果基本上只有并发为10的时候响应时间是在100ms以内的 看来我们还有很长的一段路要走啊。正所谓“最好的架构是进化而来的而不是设计出来的” 面对我们现在的瓶颈暂时通过负载均衡添加多台Web服务器就可以了。我们上面讲到负载均衡器类型的时候有一种 Microsoft负载均衡我们可以很轻松的通过服务器管理器来将这些组件安装到我们的服务器中。 安装我们就不讲了就是通过服务器管理- 添加角色和功能-在功能中选择“网络负载均衡” 然后安装就可以了。注意图中的Load balancer实际上是不存在的因为只要我们2台Web服务器安装了网络负载平衡组件在其中任意一台上建立群集就可以了图是为了方便大家理解。这样的话我们的服务器架构就成了下面这个样子192.168.1.254 就是我们暴露的外部IP地址访问192.168.1.254的请求就会转发给后面的两台WEB服务器。配置网络负载均衡在我们为上面2台WEB服务器安装NLB之后我们在其中任意一台上来新建群集然后将另外一台加入到这个群集中即可我们就在web-01(192.168.1.130)上来新建这个群集。在建立群集之前我们要确保这2台服务器都是使用的静态IP否则无法将他们加入到群集中。在web-01(192.168.1.130)上从管理工具中打开 网络负载均衡器右击“网络负载平衡群集”选择“新建群集”在“新群集连接”窗口中将 192.168.1.130添加为主机点击下一步进入 “新群集主机参数”直接下一步进入 “新群集群集IP地址” 添加窗口中的“添加” 将192.168.1.254 添加到窗口中然后点击下一步进入 “新群集群集参数”选择“多播”然后点击下一步进入 “新群集端口规则”选中全部然后点击编辑将端口范围改成 80~80协议选 “TCP”相关性选“无”点击确定回到主窗口然后点击完成。通过上面的步骤我们已经建立了一个群集并且将web-01加入到了群集中我们还需要手动将web-02也加入到群集中。在群集(192.168.1.254)上右键点击“添加主机到群集”在“将主机添加到群集连接”窗口中的 主机中输入192.168.1.131然后后面一下点下一步即可。现在我们就可以到我们的真实机器上去访问192.168.1.254了也就是说马上我们就进入测试环节了。测试结果本文中所有的测试结果都没有取第一次的结果EF也需要预热同样的查询在EF中也是有缓存的所以第一次的结果会与后面的测试结果有很大的区别后面的几次在相同参数下基本差别就不大了。可以看到现在我们的吞吐率大概平均在230左右与一台WEB服务器一台DB服务器相比处理能力又提高了50%为什么不是100%呢一台WEB服务器能处理150的并发那两台应该是300才对呀我能够想到以下原因我们的数据库服务器只有一台数据库的处理能力提不上去最终影响WEB服务器的处理能力我们采用的是虚拟机并非实际的机器他们实际上是共用CPU不知道在这种情况下对测试结果会不会有影响虚拟化专家可以分享一下。为了验证一下我再扩展了一台WEB服务器我们使用3台WEB服务器1台DB服务器看看是什么效果。我们新建一台虚拟机web-03然后将它也加入到我们的群集中。测试开始在加入第三台WEB服务器之后我们的吞吐率每秒处理请求数再次得到提升从230升至360并发处理能力再次提升56%并且大家可以看到400并发以下的平均每请求处理时间都在1s以内可喜可贺啊最后上两图让大家更直观的看一下这些性能的变化以上数据均来自本人机器上的测试虚拟机全部采用与第一台服务器同样的配置。小结在网站架构的不断演变中负载均衡起着非常重要的位置不仅仅为我们提升可靠性和可扩展性有一些比较强大的硬件设备还能提供缓存以及session机制。今天我们用到的负载均衡是Windows Server自带的一个组件它是最简单实现负载均衡的方式但是功能不是特别完善而且一旦NLB本身发生错误那么将导致所有的网站都不能访问我们后面就来通过引入APR(Application Request Router)来解决这个问题想要真正了解大型网站的架构实现而不是仅仅知道负载均衡分布式缓存数据库分离这些名词么那就来跟我一起学习吧另外我们今天只是用一个简单的页面做了压力测试只有读数据的操作还没有写的操作也没有任何复杂的事务但是别担心我们一步一步来 :) 。