1、概述

 

N层架构是一个已被行业证实的软件架构模型,通过解决诸如可扩展性、安全性、容错等内容,适用于支持企业层面的C/S应用。.NET有许多工具和特性,但是.NET还没有预定义的方法来很好的实现N层架构。因此,为了在.NET中实现很好的N层架构的设计和实现,完全理解其思想是十分重要的。然而,我们大都听到,读到,或是使用了N层架构很多年,但是还没有完全理解其思想,这篇文章试图从多方面澄清许多N层架构的基本思想,同时也提供一些实际的建议。

 

2、N层架构介绍

 

一些术语的区别和联系:

 

TierLayer

 

Tier通常意思指计算机的物理部署

一般一台单独运行的服务器是一层,许多服务器也可以算做一层,就像容灾的集群服务器。

Layer通常意思指逻辑的、功能性的软件组件群

Layer被用于软件部署,并在软件实现方面有很多的优点,并且是一个很多的N层架构设计方法。

LayerTier之间可能完全对应,也可能不完全对应,每一Layer可以运行在一个单独的Tier里,然而,许多Layers也可以运行在一个Tier

一个Layer也可以被用于运行在多个Tiers,例如下面的图2.NET的持久化包含2部分:持久层LIBWCF数据服务,在持久层(Layer)的持久化LIB总是像业务层(Layer)运行在相同的Process当中,来让业务层(Layer)适应WCF的数据服务。然而,在持久层(Layer)的WCF数据服务可以运行在一个单独的Tier里。

还有个例子,我们可以从业务层(Layer)剥离出数据验证到一个单独的库里(但仍然保持在业务层(Layer)),这样是为了客户端表现层(Layer)能实现更好的客户端交互性能,如果这样,那么业务层(Layer)的数据验证在业务表现层(Layer)允许的进程Process是相同的,其他的业务服务层(Layer)运行在一个单独的Tier

 

TierProcess

 

如果一个Layer可以运行在一个单独的进程(Process)当中,通常它也能被运行在一个单独的计算机(Tier),因此它能被认为是能够容纳一个单独的TierN层架构中,然而,这不总是正确,例如,假定有两层(Layers这种方式来实现IPCinter-Process communication)是很少基于一个非分布式的方式,就像本地共享内存,这两层(Layers)能通过2中不同的进程(Processes)运行在同一个计算机中,而非2台计算机中。除非有另外一个可选择的分布式IPC方式(例如Socket)用于在这两层(Layer)当中,这两层会被用来指容纳一层(Tier),即使他们能在相同的电脑中运行不同的进程(Processes)。

 

TierProcess

一层(Layer)可运行在一个单独的进程中;

许多层也可以运行在一个单独的进程中;

一层也可以运行在很多的进程当中。

 

 

三层架构

 

最简单的N层架构就是三层架构,它包括表现层、应用层、数据层,如图1

一层只能直接访问在他下方的公共组件,例如表现层只能方位应用层的公共组件,但是不能访问数据层,应用层是能访问数据层的公共组件,而非表现层。这样做能减少层与层之间的依赖,依赖的最小化能对层的开发、维护、升级、扩展带来益处。同时这样做也能确保层的尽可能的安全。例如,客户端层不能直接访问数据层,但是能通过应用层访问。所以数据层有了一个更高的安全保障。最后,这么做也可以避免软件组件之间的周期性依赖。

为了要求一个完全的三层架构,这三层应该运行在单独的计算机中。

 

 

三层架构

 

下面是这三层的简单描述:

表现层:用户能直接方案,例如左面UiWeb页面等等,也叫做Client

应用层:这层封装了业务逻辑(例如业务规则、数据校验)领域内容,数据访问逻辑,也叫做中间层。

数据层:额外的数据远来存储应用数据,录入数据库服务器、CRM系统、ERP系统,主机,大型机、其他遗留系统等等。我们今天通常用的是数据库服务器,对于N层架构,我们需要使用非内嵌的(non-embedded)数据库服务器,例如SQLServerOracleDb2MySQLPostgreSQL,非内嵌的数据库服务器能运行在单独的计算机上,鉴于嵌入类型数据库,例如AccessDbase等等,不能运行在一个单独的计算机上,不能运行在三层架构的数据层。

 

123或是更多层的架构

 

1-Tier所有的层仅能运行在单独的计算机中,为了实现一层架构,我们需要使用嵌入类型的不能跑一个单独的进程的数据库系统,否则,至少需要两层,因为非嵌入式的数据库通常通常运行在一个单独的计算机上(Tier

 

2-Tier:或者表现出和应用层只运行在同一台计算机,或是应用层和数据层只允许在同一个计算机,整个应用允许不能超过2台计算机。

 

3-Tier最简单的N层架构,上面的三层能运行在三个不同的计算机中,实际上,这三层能部署在同一个计算机上(三层架构,但是部署在1-Tier

 

N-Tier三层或是更多层的架构,如图2典型的N层架构,一些三层能进一步被分解为更多的层,这些被分解的层可以运行在更多地(Tiers),例如,应用层可被分到到业务层,持久层或是更多,表现出可以被分到客户端层和客户端表现层,在图2种为了要求一个完整的N层架构,客户端表现层,业务层和数据层应该被允许在三个不同的计算机上(Tiers)。

一般情况下,这些层部署在同一台计算机上(Tier

 

2  N层架构

 

下面是图2种所有层的简单描述:

客户端层:这一层被包含到直接用户当中,有许多不同种类的客户端,如WPFWindows FormHTML Web page 等等

客户端展示层:包含客户端所需的展现逻辑,例如:IIs web 服务器中的ASP.NET MVC,同样它也适用于不同的客户端对应业务层。

业务层:处理横封装所有的业务与和逻辑,也称做领域层。

持久层:对于对数据层处理书写业务数据,也被称做数据访问层(DAL

数据层:外部数据源,例如数据库

 

有时层的数量可以≥3,但是客户端展现层,业务层,和数据层不能运行在三台单独的计算机中(TIERS)。这是N层架构?我们把N层归类到一个不完全的N层架构因为他的客户端展现层,业务层和数据层不能运行在三台独立的计算机中(TIERS

如果我们使用非嵌入的数据库如SQL SERVEROracle等等,这些数据库将总是会运行在单独的计算机上,因此,图图1所示,两层架构的标准是表现出和业务层运行在一个单独的计算机上;三层架构的表示是表现出和应用层运行在不同的计算机上,一个完整的N层架构作为3层的相同标准。

 

不同层架构的优缺点

 

1或是2层架构

优点:对于少量用户,简单快速,因为进程和层少,硬件,网络,运维,部署成本较低。

缺点:当用户数量增多将会出现问题,在解决问题方面存在限制:如安全性,扩展性,容错性,因为它知呢个部署在1-2计算机上。

 

 

N层架构

 

优点:

1、扩展性:主要因为多层部署和层之间分离的能力。例如:数据层通过数据库集群而不需要包含其他层就能扩展,WEB客户端能通过负载均衡扩展而不需要影响其他的层,windows server 为了负载均衡和容错,能很容易的进行集群,另外业务层服务器也能进行集群来扩展应用,例如在J2EE中的WEBlogic集群

2、对于整个系统更好的和更精细的安全控制:我们能根据每层的安全需求不同而进行不同的安全控制,例如,业务层和数据层通常需要比表现层更高的安全控制,然后我们能将这两个更高的安全层放在防火墙后面进行保护,12层架构不能完全实现这样的目的因为有层数的限制,同时对于N层架构,用户也不能直接访问业务层和数据层,所有用户的请求通过客户端表现层路由到业务层,然后路由到数据层。因此,客户端表现出也作为业务层的类似代理的功能一样进行服务,业务层作为数据层的代理一样进行服务,这些像带来的层给下面的层提供更好的安全保护。

3、更好的容错能力:例如,数据层的数据库被集群进行容错或是负载均衡等目的而不影响其它层。

4、单独的层升级或是改变不影响其他的层,在面向对象的世界里,依赖接口的实现能很好的减弱所有的层之间的单独改变而不怎么影响其他层。依赖接口意味着一个层只依赖另一个层的接口,而非具体的类。同时,一个层和它直接的下层之间的依赖也减小了一个层改变对整个系统的影响。例如,如果保持接口不变,我们能单独的更新或替换任何层的实现,而不需要影响整个系统,因为业务需求和技术的改变,一个层的实现改变对于另一个层变的完全不同的现象经常发生,例如,起初我们主要使用Windows Form,现在我们主要使用WPF,如果我们的原始系统是通过层架构来实现的话,我们就只需要把客户端从Windows Form更新成WPF而不需要改变服务层。

5、对于开发来说比较友好和高效:层的解耦是逻辑软件组件组的主要功能,他们对于软件开发来说都非常的友好和高效,每一层可以被单独分配到一个团队专攻特定的功能区域;一个专业团队可以处理相关的任务更有效。

6、友好的维护:N层体系结构主要根据功能让不同的东西组织在一起,使清晰、容易理解和管理。

7、友好的新特征:由于逻辑分组的组件和多层体系结构带来的解耦,可以很容易地添加新的功能,而不会影响太多对整个系统。

8、更好的可重用性:这是由于部分的逻辑分组,层与层之间的松散耦合。松散耦合的组件通常是在更一般的方式实现的,因此他们可以通过更多的其他应用程序中重复使用。

 

多层部署的缺点:

 

因为包含更多的网络、计算机和进程,如果硬件和网络带宽不够好的话,整个应用程序的性能可能会很慢。

因为需要更多的硬件和更好的网络带宽,导致硬件、网络、维护和部署的成本增加。

多层部署应用程序性能的影响是个双刃剑。

一方面,如果用户的数量不够大,因为包含更多的计算机,进程和网络使得其应用性能降低,即,如果把所有东西都放在一个层或是一个过程中,对于用户较少的情况下表现可能会更好,然而,当用户数量越来越大,那么多层架构的可扩展性将会提高应用的整体性能,如负载均衡和数据库集群来提高多次结构的性能。为什么用户量小的性能结果和用户的大数目是不同的?这是因为整个应用的瓶颈在这两种情况下是不同的。对于少数用户,瓶颈是数据通信之间的不同的过程的时间。如果更多的计算机,更多的过程和更长的网络,这将花费更长的时间,那么性能差。的计算机,更多的过程和更长的网络,然后花费更长的时间,那么性能差。然而,当用户数越大,瓶颈转移到其他的东西,因为服务器的能力,如在一个计算机的CPU和内存之间的资源争夺、服务器数据库的度量阈值、一个Web服务器能力限制。只有多层架构的可扩展性才能解决这些因大量用户而导致的瓶颈,负载均衡服务器集群通常用于多层体系结构的可扩展性。随着越来越多的计算机扩展到共享任务的用户数大,才能提高性能。除了由多层体系结构的可扩展性获得性能,我们也可以使用更好的硬件,更好的网络带宽以满足业务需求更性能。

 

在多层架构的业务数据的验证

 

为了使整个业务系统的健康和完整,在N多架构中使用数据验证那是相当重要的,而且也是必须滴,业务数据验证的第一个问题是:在哪里或是哪一层应该处理数据验证?

 

1、数据验证可以在任何层检查。通常,越接近客户层的验证,性能越高,进一步的客户端层验证,来实现更可靠和更强大的应用。当在业务层和持久层进行检查作为验证时,这是保证每一个类型的客户端将得到验证,而不管客户端将检查是否验证。

2、当我们决定哪一层应该做验证,我们需要在性能、可靠性和鲁棒性之间达到一个平衡的结果,同时我们也要根据实际情况做出决定。如果我们完全控制所有的层,我们能让验证发生在客户端\客户端表现层来获得性能。然而,如果业务层也失控暴露给客户端\客户端表现层,那么业务层或是更低的层必须做所有的验证才能满足可靠性,不管客户端做不做相同的验证。

4、客户端的验证是有效的,例如网页中的JavaScript验证,然而,用户可以轻松地绕过客户端的验证,如网页的黑客攻击,需要做数据验证在客户端和服务器端实现性能和可靠性。

在业务层和其他进一步的较低层通常属于在服务器端。客户端\客户端表现层可能会也可能不会在服务器端,如如ASP.NET是一个Web服务器的客户端\客户端表现层却在服务器端,对于像WPF这样的客户端表现层可能不会在服务端。

5、一个更实际的方式是在客户端做简单的数据验证,在服务器端做更为全面的验证,简单的数据验证主要是对一个一个实体用例单个属性的检查。全面的验证包括简单的数据验证和一些复杂的数据验证。复杂的数据验证包括横跨一个实体用力相同或不同类型的多个属性的类级别的数据验证。

6、我们在一个地方应该实现和维护一个版本的数据验证逻辑,不管验证在哪里被Checked,所有的层都应该共享这一版本的数据验证逻辑,为什么?这样做有更好的可重用性,在许多地方,这样可避免重复和冲突的验证逻辑,使开发,维护和部署更加容易,它在整个应用程序保持一致的验证逻辑。此外,验证检查的地方,可能会随着不断变化和日益增长的业务而改变,所以应存放在一个地方,一个版本,如果需要的话,可被任何层灵活使用。

 

如何正确部署N层应用程序

 

更多层带来了额外的复杂性、额外的部署/维护的工作量和额外的成本。因此,层数应保持最小来解决可扩展性,安全性,故障转移等问题,如果这些问题都需要解决,不要进一步部署更多层的。但是为了尽可能更好的解决这些问题,通常至少石永红三层架构,如果这些问题在某些情况下不是太CARE,那么我们选择12层架构进行部署来满足性能要求。多少层算最好的呢?没有固定的答案,为了满足我们的业务需求,我们需要选择层的数量来实现好的坏的最佳的平衡效果。

我们应有所区别以下两种情况:1)一台计算机运行在一个进程中的所有层,和b)不同进程中的一台计算机中运行的所有层。第一种情况实际上是三层架构,第二种情况是通常的N-Tier架构,但仅仅部署在1TIER。即使两者都是在一台电脑,1层架构将由于较少的过程中将会有更好的表现。相比较与一个进程,进程之间相互通信是复杂和较慢的,不管使用什么类型的IPC(进程间通信):如TCP/IP、命名管道、消息队列、共享内存等。因此,在一个计算机上部署,我们需要确保应用进程的数量尽可能少来满足性能要求。如何实现呢?N层架构能通过在不同的层之间进行切换的这种方式来实现,并且仅仅更新配置文件还是相对容易的。此外,3层架构,可以部署为3层或更少。但2层架构不能被部署为3层,否则它应该被称为3层,而非2层。

 

 

如何通过软件技术实现N层部署

 

N层的主要特点是能够在不同的计算机上部署一个或多个层来处理来解决诸如可扩展性,安全性,容错等问题。如何实现2层之间的通信呢?应用程序是运行在一个TIER里的进程当中,所以,两层之间的通信实际上归结到IPC(进程间通信)问题。分布式IPC方法可以支持两个过程在两个不同的计算机沟通,如插座,分布式消息队列等,本身这些分布式的IPC方法可以支持N层部署能力。例如,如果两个层与TCP / IP采用(SOCKET)套接字的通信方式来实现的,这两个层可以部署在两个不同的计算机(层级)互相通信。在NETWCF可以轻松实现​​N层部署要求,WCF支持进程间的通信,无论是在同一台计算机或不同计算机,WCF是建立在基本IPC方法之上。使用WCFN-Tier架构的另一个优点是,WCF是一个非常松散的耦合层之间的依赖,能够实现SOA(面向服务的架构)。

 

 

N层架构开发的一些实用技巧

设计,实施,部署和维护的N层体系结构是非常艰巨的任务。在一开始如果你没有明确的全局的想法,你可能最终由于迂回和扭曲,在这里和那里浪费了大量的时间。我们已经谈到上述部署和数据验证的一些技巧,在这里,我们将提供一些额外的N-Tier架构开发的实用技巧。在这篇文章中的技巧是基于一个团队完全掌握一个完整的N-Tier架构的所有层。

 

1、通过一些松散耦合技术来实现层与层之间的解耦,例如SOAP XML Interface。在面向对象世界里,每一层都应该只取决于其直接下层接口,而不是由具体的类。通过这样做,我们就可以实现最高两层之间脱钩,这种脱钩发展将带来许多好处,单元测试,维护,升级,互换性,可重用性等。

2、尽可能的尝试自动生成和维护一个版本的POCO业务实体类,他能在整个应用程序中重用,为什么呢?业务实体类是N层架构的基础,他能从最顶层到最底层传达消息。现代的英语趋向于越做越大,因此,手动创建大规模的实体类是艰巨的,而且容易出错,特别是有些人喜欢在不同的层使用不同的版本。因此,我们建议在整个应用程序中,应该尽量只使用一个轻量级的POCO实体类的版本(自动生成的代码)。这样做会为我们节省了很多工作,也消除了映射和实体类的不同版本导致许多不一致的毛病。有许多代码生成器,如代码生成实体框架。当然,不同的层中可能有不同的要求,对实体类,我们可以使用注解功能类System.ComponentModel.AnnotationC#的部分功能,在特殊层的特殊需求中应该限制或扩大这些自动生成实体类。如果我们必须在不同层使用不同的版本的某些实体类,我们可以使用数据传输对象(DTO)映射到这些具体的实体,并且仍能够保持主要的实体类是只有一个版本。

3、使用一些自动工具包生成业务实体类和传统的关系型数据库(数据层)之间的映射。随着业务和数据库之间的映射转换变得越来越多,手动创建这些映射是不容易的,很容易出错。有许多现有的包或工具来帮助我们,如实体框架和NHibernate for NET,和Hibernate for Java

4、为大量和样式相似的代码尽量使用代码生成器。如果不能找到能满足你需求的代码生成器,那么就自己开发一个,使用面向对象编程语言(如C#或Java),同时配合XSLT,开开发满足你需求的代码生成器不是太难,XSLT是基于XML的,代码生成是十分有用和灵活的,他能很容易把任何XML文档转换层任何文本。

5、要把持久层和业务层是紧密结合是非常轻松容易的,但是我们应该避免这种情况。例如,.NET中,一个WCF业务服务层可以直接访问实体框架。这种情况是非常受欢迎的。但是,这样做有问题,业务层和持久层的紧密耦合会给每一层的单元测试、升级、互换带来很多问题,通常我们需要这两者之间做一个适配器层,这只需要一个简单的接口。

6、在客户端表现层,我们应该尽可能的将所有的客户端公共代码放到一个Library里,来最大化代码的可重用性。

7、缓存曾可以被添加到任何现有的层来提高性能,例如Varnish accelerator(HTTP 加速器)asp.netDrupal或其他Web应用程序中的客户端层和客户端表现层之间作、一个缓存层来提高性能。

MemcachedAPC缓存是PHP的缓存包,缓存包可以被作为单独的业务数据缓存层添加到PHP的层当中。请求首先会去缓存层,如果有效的数据是在缓存中,然后请求Request将返回,并不会进一步去到下层,那么这样性能就得到了提高。一般情况下,更新或是过期的数据将会使缓存中的数据变成无效的旧数据,在.net 4中的命名空间System.Web.Caching可以用于ASP.NET的缓存,命名空间System.Runtime.Caching可以缓存在任何地方,企业库中的缓存应用程序块也是一种选择。

8、为了适应多变的业务需求和技术,通过这种方式实现的N层架构可以有助于更灵活的部署任何类型的应用,当然也包含2层架构的部署,例如,通过这种方式实现的N层架构可以简单地通过修改配置文件中的一些参数值来切换成不同的架构

 

 posted on 2013-06-15 18:56  Jungle  阅读(6021)  评论(0编辑  收藏  举报