关于大型ASP.NET应用系统的架构—如何做到高性能高可伸缩性

  简介

  前面一篇《关于大型ASP.NET应用系统的架构-架构的选择》写完之后,有一些同仁热心回复,有的是提问题,同时希望能举一些例子来说明;有的是提建议,希望下一篇写得更详细点;还有的同仁提出不同的观点。感谢大家的参与。会继续努力的。本文将针对Layer和Tier的区别做个辨析。并详细介绍3 Tier / N Tier架构中各Tier的开发。各Tier的分布式方式。以及为了达到高性能,低延迟,高可伸缩性,需要采取哪些方法和手段。

  关于“大型ASP.NET应用系统 ”的概念

  意指能支持同时在线用户数目很多的ASP.NET应用系统。同时在线用户数目要达到多少才算大型。其实也没有一个可以作为共识的定义,个人认为如果一个应用系统能做到7x24小时同时在线用户数不少于5000的,应该可以称为大型应用系统。例如:微软的官网(www.microsoft.com),7x24小时都有来自全球的人访问,有查阅MSDN的,有访问微软博客的,有看微软产品信息的,有逛微软论坛的,等等等等。同时访问微软官网的人太多了,远多于5000。还有Myspace。 它有总数为几千万的用户,它的同时在线用户数也是相当惊人的。它之所以能服务众多的用户,是因其背后有一个庞大的系统来支撑。

  层Layer和排Tier的辨析

  这里针对上篇的评论,对层Layer和排Tier做个辨析。上篇提到了分层Layer的架构只能部署在同一台服务上,有同仁在评论里提出不同意见,说分层的架构也可以部署到多台服务器上的。层Layer是指应用程序各功能在逻辑上的分组,而排Tier表示了应用程序各功能是物理分部在多台计算机上。层Layer很好理解,就是相同功能的类被逻辑上分到了一组,如:数据存取的类都放到了一块,在同一个名称空间下,在同一个程序集里,商务逻辑的类也是一样进行分组,各组之间有统一的调用形式。如商务逻辑的类引用数据存取的类,调用其方法,取得返回结果。同时UI层可调用商务逻辑层的类。商务逻辑层的类既有服务UI层的功能,也有调用数据访问层的功能。是个承上启下的层。这些层都是按照功能来划分的。层Layer是一种逻辑上的划分。排Tier是特指物理的划分,应用程序的各功能,分别被放在了不同的服务器上,如UI功能单独占用一些服务器,商务逻辑功能占用另外的一些服务器。这两种功能部件之间有服务器的边界,那么就有专门负责分布式调用的功能部件。如果单从功能逻辑上看,排Tier中也是有层Layer的,只是比传统层Layer的划分多了一些用于分布式调用的层Layer。排Tier是各层Layer物理分离后,再加入一些负责分布式调用的层Layer才形成的。排Tier和层Layer是有着联系的。从这个意义上说,排Tier是层Layer物理分离时的特例。有层Layer物理分离的情况下,可以称之为分层的架构,但是实际上这并不准确,因为排Tier是专门为这个场景定义的。有物理分离,就叫排Tier更准确些。层Layer只要一做物理分离,就转化成了排Tier。

  从部署角度试图来区别分层Layer的架构和3 排Tier / N 排Tier的架构。因为物理分离的场景已经被定义成排Tier,那么剩下的就只能是物理不分离的场景了。所以分层Layered架构就特指部署在同一台服务上的场景(即物理不分离),3 排Tier / N 排Tier架构就特指各层Layer物理分离的场景。分层的架构部署到多台服务器上,理论上是可以的,但是光靠原有的层是不够的,有了服务器的边界之后,原来在同一个进程里面的方法调用就不再可行,必须新加一些层来做分布式的调用,才能让原来的各层运行起来。等做完这一切,发现这个架构再叫分层Layered的架构就不合适了,必须得叫3 排Tier / N 排Tier架构才合适。

  层Layer和排Tier之间有联系,分层Layered的架构和3排Tier / N 排Tier架构可以互相转化。

  整体映象

  从前面的描述中可以得知应用系统的每一排Tier都是由许多服务器来完成的。比如UI排Tier,可以是几十个服务器,几百个服务器,甚至是几千个服务器。具体每一个排Tier所需服务器的数目根据实际的需要来配置。所谓实际的需要就是看这一排Tier服务器的硬件资源利用率。比如CPU, 内存,磁盘读写等情况,如果相当高,就必须加入新的服务器部署该排Tier同样的应用到新服务器上。让新的服务器也能分担些压力。其实这就是要让应用程序能支持高可伸缩性。在每一个排Tier之间有硬件负载均衡,再其后就是下一个排Tier的服务接口了。在其服务接口之后才是该排Tier的服务。

  除了高伸缩性之外,还有如何保证高性能。即应用程序必须是良好设计的。在每一个排Tier的内部,可以采取一些措施让应用程序的执行效率达到最高。让硬件的资源得到充分的利用。这有一些策略,如缓存。减少访问数据库的次数,等等。以下是一个可伸缩的ASP.NET应用系统的整体映象图:

The big picture  一个在互联网上的用户的请求的处理过程是这样的:

  1. 首先经硬件负载均衡处理,选定一个Web服务器来响应这个请求,然后将该请求交给该服务器

  2. 此Web服务器执行所请求的页面,该页面的后端代码先查询缓存服务器,即调用缓存服务接口查询是否已经有缓存,如果有,就直接返回缓存的结果。

  3. 如果缓存里没有就调用商务逻辑服务接口,进而调用商务逻辑服务。商务逻辑服务执行时,如果需要访问数据库,会先检查缓存中是否有缓存的数据库内容,如果有,就会用缓存的数据库内容来进行商务逻辑的计算。如果没有缓存,就会调用数据访问接口以存取数据。

  4. 类似地,数据访问服务也会查看缓存,然后根据所要求的数据内容去访问相应的数据库,如果是只读的请求,数据访问服务可以将数据库访问请求发给做日志复制的数据库服务器。如果是写的请求,可以发给主数据库服务器

  5. 数据库服务器执行应用的Sql请求,返回结果。再由数据服务返回给商务逻辑服务。

  6. 商务逻辑服务再返回给Web服务器,由Web服务器生成页面内容返回给互联网上的用户。

  以上过程与分层Layered的架构类似,只是比分层Layered的架构多经过了几个服务接口。如果没有这些服务接口,因为UI排Tier,商务逻辑排Tier,数据访问排Tier是在不同的服务器上的,它们根本就不能直接对话。因为它们是在不同的.NET VM中的。它们必须得借助与这些服务接口才能互相之间进行调用。这些服务接口具体的组成技术可以是WCF,也可以是.NET remoting,等。应该说目前最好的选择是WCF。

  UI排Tier

  关于SessionState的技术方案

  为了让应用程序具有可伸缩性,必须让每一排Tier都有负载均衡的特性,也就是要做到用户的请求由任何一个同一排Tier中的服务器来处理都不会有任何问题。关于用户的Session的处理就必须有一个妥善的解决方案。有不少人不赞同采用SessionState,觉得SessionState对ASP.NET应用的性能影响比较大。还有人写文章说同一个SessionID的AcquireRequestState会在页面代码前获得对Session对象的锁,因此容易有较大的延迟,对性能影响不小。另外的人认为Session占用服务器的内存比较多,同时需要一些CPU资源来将Session中的对象序列化和反序列化。所以一种比较普遍的观点是不采用ASP.NET本身提供的Session机制。其实采用SessionState和不采用SessionState都各有特点。了解其特点后再做权衡取舍才比较合适。

完全不采用SesstionState

  完全不采用SesstionState是在Web.config中写上<sessionState mode=”Off”/>     或者   <Pages enableSessionState=”Off”/>来禁止SessionState。那整个应用的所有页面都不会用SessionState。其实这不全面,http请求处理周期里还有一个系统默认的httpmodule在处理SessionState。还须在Web.config加一句:

<httpModules>
<remove name="Session" />
</httpModules>

NET技术关于大型ASP.NET应用系统的架构—如何做到高性能高可伸缩性,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。