前文讲过,在实践中,人们总结出了一些常用的软件系统结构高层模式,以供应用系统设计时参考。这些模式包括:单服务两层/多层C/S;MVC结构;面向服务的SOA与多服务集合;数据交换总线等。
1. 单机应用系统(Standalone)
准确地讲,单机应用系统是最简单的软件结构,是指运行在一台物理机器上的独立应用程序。当然,该应用可以是多进程或多线程的。
在信息系统普及之前的时代,大多数软件系统其实都是单机应用系统。这并不意味着它们简单,实际情况是,这样的系统有时更加复杂。这是因为软件技术最 初普及时,多数行业只是将软件技术当做辅助手段来解决自己专业领域的问题,其中大多都是较深入的数学问题或图形图像处理算法的实现。
有些系统非常庞大:笔者早年曾经参与的一个大型纯软件系统开发,多达160万行程序!要知道,这些程序当时可都是一行行写出来的。这应该算是一个超 大型的软件系统了,共有十多个子系统集成在一个图形界面上执行,并可在多行UNIX/DOS平台下运行,其中很多算法的复杂困难程度,可以说,如果讲给今 天这些所谓的架构高手与计算机高手听,他们会感觉如听“天书”一般深奥;有些系统则算法非常复杂:我的一个同学,在他们专业领域内编制的软件程序,在当时 *的专业工作站上(应该要比今天的最快的微机性能还好些),一敲回车键运行,就往往要等待一个星期的时间才能得到结果。
而这些软件系统,从今天的软件架构上来讲,却很简单,是标准的单机系统。即便是今天,复杂的单机系统也有很多,它们大多都是专业领域的产品,如 CAD/CAM领域的CATIA、ProEngineer,Autodesk的AutoCAD,还有我们熟悉的Photoshop、CoralDraw, 等等(这些系统的高级版本可能提供了一些网络化的功能,但改变不了其单机系统的实质)。
所以这里笔者要说的是,软件架构复杂并不代表软件系统复杂,其实,软件架构设计较为重要的领域只有一个,那就是信息系统领域,即以数据处理(数据存储,传输,安全,查询,展示等)为核心的软件系统。其他行业的软件应用对该概念其实并不是那么强调。
所以,读者应该明白,后面几节介绍的所谓流行软件架构,都是指在信息系统的领域内。
2. 客户机/服务器(Client/Server)结构
客户机/服务器结构是软件系统中最常见的一种。笔者认为该概念应该来源于基于TCP/IP协议的进程间通信IPC编程的“发送”与“反射”程序结 构,即Client方向Server方发送一个TCP或UDP包,然后Server方根据接收到的请求向Client方回送TCP或UDP数据包(这里是 指建立TCP/IP连接以后的应用程序逻辑,不涉及如TCP建立连接的三方握手过程),IPC编程的客户端/服务器概念图如图6-2所示。
诚然,上述IPC编程中的客户与服务,在过去只是一个再普通、传统不过的标准程序结构与编程方法,不会有人将其提高到软件架构的高度。但其实,现代 流行的各种C/S架构,其本质却正是如此:即TCP/IP IPC编程中的客户机/服务器。目前为止,还没有任何一种客户机/服务器架构的软件超出了这个范围。
所以,准确地讲,现代各种客户机/服务器模式的软件架构实际上是对IPC编程中客户/服务程序结构更加产品化与成熟化的结果。
让我们来看看几种常见的客户机/服务器的软件结构。
● 两层C/S
两层C/S,其实完全是IPC客户端/服务器结构的应用系统体现。两层C/S其实就是人们所说的“胖客户端”模式。
在实际的系统设计中,该类结构主要是指前台客户端+后台数据库管理系统,如图6-3所示。
在两层C/S结构中,图6-3前台界面+后台数据库服务的模式最为典型,前文所说的很多数据库前端开发工具(如PowerBuilder、Delphi、VB)等都是用来专门制作这种结构的软件系统的。
有人也许要问,上述典型的两层C/S模式应该没有你所说的TCP/IP通信呀?怎么你前面讲所有的C/S模式都脱离不了这个范围呢?其实,每一种数 据库都提供了其专用的访问API或通用的ODBC/JDBC接口,如果这个数据库的开发支持从不同的机器上以网络方式连接,则笔者相信其在客户端与数据库 后台的通信大多情况下是TCP/IP的客户机/服务器模式!如果这个数据库不支持网络连接方式(如以前基于FoxBase的开发,或现在基于MS Access的开发),则我们不能称这个软件是C/S模式。
另外,如图6-3所示,两层C/S实际上是将前台界面与相关的业务逻辑处理服务的内容集成在一个可运行单元中了。
● 三层C/S结构与B/S
三层C/S结构如图6-4(a)所示,其前台界面送往后台的请求中,除了数据库存取操作以外,还有很多其他业务逻辑需要处理。三层C/S的前台界面与后台服务之间必须通过一种协议(自开发或采用标准协议)来通信(包括请求、回复、远程函数调用等),通常包括以下几种:
(1)基于TCP/IP协议,直接在底层socket api基础上自行开发。这样做一般只适合需求与功能简单的小型系统;
(2)首先建立自定义的消息机制(封装TCP/IP与socket编程),然后前台与后台之间的通信通过该消息机制来开发。消息机制可以基于XML,也可以基于字节流(Stream)定义。虽然是自开发,但可以基于此构建大型分布式系统;
(3)基于RPC编程;
(4)基于CORBA/IIOP协议;
(5)基于Java RMI;
(6)基于J2EE JMS;
(7)基于HTTP协议。如浏览器与Web服务器之间的交流便是如此。需要指出的是,HTTP不是面向对象的,所以面向对象的应用数据会被首先平面化后进行传输。
目前最典型的基于三层C/S结构的应用模式便是我们最熟悉、较流行的B/S(Brower/Server,浏览器/服务器)模式,如图6-4(b)所示。
图6-4(b)的B/S结构中,Web浏览器是一个用于文档检索和显示的客户应用程序,并通过超文本传输协议HTTP(HyperText Transfer Protocol)与Web服务器相连。该模式下,通用的、低成本的浏览器节省了两层结构的C/S模式客户端软件的开发和维护费用。这些浏览器大家都很熟 悉,包括MS Internet Explorer、Mozilla FireFox、NetScape等。
Web服务器是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连到服务器上并请求文件或数据时,服务器将处理该请求并将文件或数 据发送到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)进行信息交流,这就是人们常把它们称为 HTTPD服务器的原因。
我们每天都在Web浏览器上进行各种操作,这些操作中绝大多数其实都是在Web服务器上执行的,Web浏览器只是将我们的请求以HTTP协议格式发 送到Web服务器端或将返回的查询结果显示而已。当然,驻留Web浏览器与服务器的硬件设备可以是位于Web网络上的两台相距千里的计算机。
应该清楚,B/S模式的浏览器与Web服务器之间的通信仍然是TCP/IP,只是将协议格式在应用层标准化了而已。实际上B/S是采用了通用客户端界面的三层C/S结构。
● 多层C/S
多层C/S结构一般是指三层以上的结构,在实践中主要是三层与四层,四层即前台界面(如浏览器)、Web服务器、中间件(或应用服务器)及数据库服务器,典型的客户机/服务器软件结构如图6-5所示。
多层客户机/服务器模式主要用于较有规模的企业信息系统建设,其中中间件一层主要完成以下几个方面的工作:
(1)提高系统可伸缩性,增加并发性能。在大量并发访问发生的情况下,Web服务器可处理的并发请求数可以在中间件一层得到更进一步的扩展,从而提高系统整体并发连接数;
(2)中间件/应用层一层专门完成请求转发或一些与应用逻辑相关的处理,具有这一作用的中间件一般可以作为请求代理,也可作为应用服务器。中间件的 这种作用在J2EE的多层结构中比较常用,如BEA WebLogic、IBM WebSphere等提供的EJB容器,就是专门用以处理复杂企业逻辑的中间件技术组成部分。
(3)增加数据安全性。在网络结构设计中,Web服务器一般都处于非军事区,即直接可以被前端用户访问到,如果是一些在公网上提供服务的应用,则 Web服务器一般都可以被所有能访问与联网的用户直接访问。因此,如果在软件结构设计上从Web服务器就可以直接访问企业数据库是不安全的。因此,中间件 的存在,可以隔离Web服务器对企业数据库的访问请求:Web服务器将请求先发给中间件,然后由中间件完成数据库访问处理后返回。
● MVC
MVC的概念在目前信息系统设计非常流行,严格来讲,MVC(Model-View-Controller)实际上是上述多层C/S结构的一种常用的标准化模式,或者可以说是从另一个角度去抽象这种多层C/S结构。
在J2EE架构中,View表示层指浏览器层,用于图形化展示请求结果;Controller控制器指Web服务器层,Model模型层指应用逻辑 实现及数据持久化的部分。目前流行的J2EE开发框架,如JSF、Struts、Spring、Hibernate等及它们之间的组合,如 Struts+Spring+Hibernate(SSH)、JSP+Spring+Hibernate等都是面向MVC架构的;另外,PHP、 Perl、MFC等语言都有MVC的实现模式。
在以前传统JSP程序中网页与数据访问是混合在一起的,在MVC中强制要求表示层(视图)与数据层(模型)代码分开,而控制器(如Servlet)则可以用来连接不同的模型和视图去完成用户的需求。
从分层体系的角度来讲,MVC的层次结构如图6-6所示,控制器与视图通常处于Web服务器一层,而根据“模型“有没有将业务逻辑处理分离成单独服务处理,MVC可以分为三层或四层体系。
● 对分层标准的探讨
以上所讲各种C/S结构,包括两层、三层、四层甚至多层的概念,在IT界目前非常流行,绝大多数的信息处理系统与门户网站,都会将自己应用的结构宣传为多少多少层C/S架构。但究竟应该是属于多少层,两层还是三层?目前的实际状况是比较混乱的。
例如上面所说B/S结构,有人说是三层,也有不少人说是两层,各有道理;又比如MVC,有人说是四层,又有人说是三层,同时在很多宣传中它确实被归结到J2EE宣传的四层架构中;另外,还有许多应用系统在某一层采用主从模式的集群服务器结构,有时也会使分层的概念混淆。
本书在这里给出一个分层问题的判断标准,即应该将应用系统的分层与服务分级区别开来。即某个应用架构到底分多少层,应该由其纵向深度上有多少个不同 种类的(服务器集群显然排除在外)、两两相互通信的独立运行单元组成来决定;而服务分级应该由其纵向深度上以其由多少个不同类型的服务实例以两两双向通信 的模式组成?也就是说,一共由多少对简单客户机/服务器组成。
于是,B/S应该是三层架构,但是由两级不同类型的服务组成:Web服务与数据库服务;而四层架构则通常应该是由三级服务组成的。还有,在有些 J2EE框架(如JSF+Spring+Hibernate),除了Web服务器与浏览器的通信以外,再没有其他的分布式应用了(没有用到EJB,RMI 或JMS),而有些人将HibernateDAO等的数据持久化层单独算做一层,称之为四层,这也是不妥当的,因为数据持久化层与数据层毕竟不是一组客户 机/服务器的关系,因此,统一算做数据层,所以应该还是归为三层架构;
前面所说“服务”的概念,无论在Windows平台还是UNIX平台,都应该是很清楚的:服务是主机提供的功能,它以被动等待信号或定期启动的方式来实现。在UNIX-LIKE的系统中,服务一般是由Daemon来实现的。
而这里需要指出的是,上面所说的“服务”与6.2.2.3节要讲的“多服务结构SOA”中提出的“服务”涵义是不同的:多层结构的软件系统,无论其本身由多少层级的服务组成,对外都是一个完整的单点应用系统,对应SOA中的一个“服务”。
3. 多服务结构(SOA)
以上所讲,无论多少层的C/S软件结构,对外来讲,都只是一个单结点应用(无论它由多个不同层的“服务”相互配合来完成其功能),具体表现为一个门户网站、一个应用系统等。下面我们讲多个单点应用相互通信的多服务结构。
● 多服务结构
如果两个多层C/S结构的应用系统之间需要相互进行通信,那么,就产生了多服务结构,称为Service Oriented Architecture。如图6-7所示:
在SOA的概念中,将由多层服务组成的一个结点应用看作是一个单一的服务。在SOA的定义里,对“服务”的概念进行的广义化,即它不是指计算机层面 的一个Daemon,而是指向外提供一组整体功能的独立应用系统。所谓独立应用系统是指:无论该应用系统由多少层服务组成,去掉任何一层,它都将不能正常 工作,对外可以是一个提供完整功能的独立应用。这个特征便可以将多服务体系与多层单服务体系完全区分开来。
两个应用之间一般通过消息来进行通信,可以互相调用对方的内部服务、模块或数据交换、驱动交易,等等。在实践中,通常借助中间件来实现SOA的需求,如消息中间件、交易中间件,等等。
多服务结构可以在实践中又可以具体分为异构系统集成、同构系统聚合、联邦体系结构等,在下面我们对此会作一介绍。
● Web Service
多服务结构体现在Web应用之间,就成为了Web Service,即两个互联网应用(如门户网站)之间可以相互向对方开放一些内部“服务”(可以理解为功能模块、函数、过程等)。现阶段,一个Web应用 对外开放其内部服务的协议主要是SOAP与WSDL,其资料很多,本书不对其做详细介绍。
Web Service是多服务体系结构的一个最典型、最流行的应用模式,但除了其由Web应用为主而组成的特点以外,Web Service最主要的应用是一个Web应用向外提供内部服务,而不像传统意义上SOA那样有更加丰富的应用类型。
● 多服务结构的实质
多服务结构的实质是消息机制或远程过程调用(RPC)。虽然其具体的实现底层并不一定是采用了我们所熟悉的RPC编程技术,但两个应用之间的相互配 合确实是通过某种预定义的协议来调用对方的“过程”实现的,这与我们6.2.2.2节所讲多层架构的单点应用系统中,两个处于不同层的运行实例相互之间通 信的协议类型基本是相同的。
4. 企业数据交换总线
实践中,还有一种较常用的架构,即企业数据交换总线,即不同的企业应用之间进行信息交换的公共通道,如图6-8所示:
这种架构在大型企业不同应用系统进行信息交换时使用较普遍,在国内,主要发生在银行或电信等信息化程度较高的行业。其他的许多行业虽然也有类似的需求,但大多都是手工或半自动化来实现该项需求的,并没有达到“企业数据交换总线”的层次。
关于数据总线本身,其实质应该是一个可称之为连接器的软件系统(Connector),它可以基于中间件(如消息中间件或交易中间件)构建,也可以 基于CORBA/IIOP协议开发,主要功能是按照预定义的配置或消息头定义,进行数据(data)、请求(request)或回复(response) 的接收与分发。
从理论上来讲,企业数据交换总线可以同时具有实时交易与大数据量传输的功能,但在实践中,成熟的企业数据交换总线主要是为实时交易而设计的,而对可 靠的大数据量传输需求往往要单独设计。如果采用CORBA为通信协议,交换总线就是对象请求代理(ORB),也有一些资料中将这种架构称为“代理体系”。 另外,在交换总线上挂接的软件系统,有些也可以实现代理的功能,各代理之间可以并行或串行的方式进行工作,通过挂接在同一交换总线上的控制器来协调各代理 之间的活动。
在实践中,为客户或某个应用进行系统架构设计或提供建议,往往是对常见几种架构的选择或根据用户需求对它们进行组合。但在具体的设计中,上述每一种常见架构都会衍生出许多不同的实例。
对用户的需求设计或选择不同的架构,往往不是出于满足功能的需求,而是为了满足或达到最佳性能考虑。下面本书将会介绍几个从实践中抽象出来的较常用的架构组成部分的选择依据。它们都不是完整的架构,但却在架构设计中经常遇到。
1. 两层、三层还是四层
● 普通常识
如果采用专用“胖客户端”设计,用VB、VC、PowerBuilder、Java Application等手段制作前台界面,并与数据库直接交流,则毫无疑问,我们的软件是最简单的两层C/S架构。
现在您要为某企业设计一个可处理网上业务的门户网站,无论你采用J2EE、.Net或PHP等工具或技术,一般的常识是:
1. 如果涉及复杂的业务逻辑,则一般在Web SERVER与数据库服务器之间,会设计专门的应用服务器层(若采用J2EE技术,则可以考虑采用EJB及其容器来实现该层)。则除去浏览器以外,我们的 设计架构将会有Web服务器、应用服务器及数据库服务器三级服务,为四层架构;
2. 如果不涉及复杂的业务逻辑,绝大多数Web请求都是数据库操作,则一般由Web SERVER上部署的程序直接访问数据库,即我们的设计架构将会有Web服务器及数据库服务器两级服务,为三层架构;
这里首先要纠正一个观点。例如对J2EE的开发者而言,对上述第2种情况,他们可能采用了JSP+Servlet+JavaBean+DB的程序结 构,则他们认为自己的架构是四层,这个观点是不正确的。如果没有使用专业中间件(如WebLogic)的EJB容器,JSP、Servlet及 JavaBean都是在Web Server服务器上运行的,所以其实只有Web服务器层及数据库服务器两级服务,应该还是三层架构。包括现在较流行的Struts、Spring、 Hibernate、JSF等J2EE的框架技术,无论您的程序结构最终是JSP+BB(Bean)+Spring代理+Hibernate DAO+DB还是JSP+Servlet+DB,其实质都是三层架构,其间的区别只在于程序结构的优化上,而不存在实质性的架构优势的区别。
以上是大多数软件工作者在日常设计中的基本原则,这自然是正确的。而本书在这里则要对上述第二种情况做进一步探讨,以为广大软件设计者参考。
● 深一步探讨
在上述第2种情况中,我们要设计的系统没有复杂业务逻辑,只有大量的数据库请求操作。对这种应用需求,目前在国内,绝大多数的开发者都自然遵循了上 述原则,采用三层C/S架构(即B/S)来实现,加之现今J2EE的流行与各种程序框架(Structs、JSF等)对这种开发模式的强大支持(一般直接 采用J2EE框架提供的固定模板模式就可以很方便地搭建这样的系统),使该软件模式几乎占了这一类系统开发的80%以上的比例。
但对一个资深的设计者来讲,只了解这些是不够的。对一个中小企业的门户网站或仅供企业内部使用的一些基于Web的应用系统开发,一般可以如上述那样在开发工具与框架模式的支持下直接构建,但对于具有以下性质的门户网站开发,则不能这么简单的处理:
■ 对数据安全性要求高;
■ 各种应用系统之间数据交流频繁;
■ 直接针对互联网客户;
■ 访问量巨大,并发要求高。
与具有复杂的业务逻辑就要考虑引入基于EJB的应用服务层一样,设计者此时同样要考虑在Web服务器与数据库服务器之间加入一层的必要性,我们可以将其称为代理层服务,即设计为四层架构,如图6-9所示:
之所以叫代理层,是因为该层不处理任何业务逻辑(与上面第1种情况中的应用服务器层完全不同),只是代理执行Web服务器上的请求并向其返回结果。
代理层存在的原因有几下几点:
■ 一般重要企业的核心数据不可以能被处于网络上非军事区的、面向公众的Web服务器直接访问;
■ 多一层的设计无疑增加的系统的可缩放性,大大提高系统并发性能;
■ 将以前两层设计中对请求的完全同步处理改变为伪异步处理,大大提高处理大量并发请求的能力;
■ 可以方便地与其他应用系统进行数据或业务交流,如图6-9所示。
代理层一定是一个多线程/多进程的服务,它可以以下几种方式实现:
■ 在J2EE技术体系内,代理层可以是JMS消息容器(如IBM MQ、Java MQ、WebLogic、JBOSS等),而Web服务器与代理层则可以通过JMS消息机制交流;
■ 自开发多线程/多进程的消息服务器。采用这种方式具有较大的灵活性,Web展示层不必受到开发语言的限制(例如,如果采用JMS机制,则 Java/JSP的选择不可避免),可选择JSP、PHP、PERL、ASP、C/C++等任何一种语言来构建Web层。笔者自开发的产品“消息服务器 AMS”便是该项应用的典型,详细内容可参见www.alder.com.cn产品部分。
2. 四层以上的多层体系
除了最普通的两层/三层及较复杂的四层结构外,实践中,多层结构的单点应用系统一般到四级服务(五层)还是可以见到的,但再多的分层已经很少见,并且意义已经不是很大。所以本小节专门介绍一下四级服务(五层)的体系结构。
按上面所述的分层标准,四级服务(五层)体系中应该共包括四组两层客户机/服务器模式,如图6-10所示:
将一个系统设计为四级服务(五层)体系,一般不会再是单纯为了提高可缩放性、性能或系统安全性,主要可能是基于以下几种考虑:
■ 中间层一与中间层二一般要分别处理两种不同的业务逻辑,并且大多情况下无法合成为一个服务;
■ 中间层一与中间层二的业务必须分布在两个不同的物理区域来处理;
■ 中间层一为中间层二的预处理,即请求必须经过中间层一的处理后,然后交给中间层二进行实际的业务逻辑处理。
从图6-10可以看出,中间层一也有可能与数据库服务器交流(如图6-10中虚线所示),这完全根据其所需要处理的业务逻辑的需要而定,所以,四级 服务(五层)体系中,数据库层不一定非要严格设定为只能被中间层二访问,限制客户端对其的访问已经完全可以满足多层体系对企业数据安全的要求了。
以一个电信行业的门户网站为例,其体系结构一般可设计为四级服务(五层),如图6-11所示:
在该例中,数据处理服务器具有以下责任:
■ 接受所有Web服务器发来的请求;
■ 处理用户登录,用户数据查询,用户数据修改等功能;
■ 转发所有有关电信业务处理的请求给电信业务服务器。
电信业务服务器具有以下责任:
■ 完成业务相关一级的用户认证;
■ 处理电信业务相关的请求。这种请求的处理一般都是通过与其他业务系统交流来实现的,例如用户的请求如果与计费系统相关的话,则需要将请求再转发到计费系统去处理(电信行业的计费系统往往是另外一个独立的业务系统)。
以上电信行业四级服务(五层)体系中,除与数据库服务器的交流以外,各个客户机/服务器组之间一般采用消息机制来实现通信,如JMS或行业自定义的消息协议,实践中很多企业都采用基于XML的消息体定义。
3. 服务器集群
在多层C/S架构中,每一层可能会有多个服务器协同工作的需求。这些需求一般可以总结为以下几个方面:
■ 上一层的请求太多,一个服务器无法满足需求;
■ 即使一台服务器崩溃掉以后,可以由其他服务器继续负责应用程序的运行;
■ 要求不同的服务器负责处理不同性质的请求。
因此需要根据某种机制将请求分配到多个服务器上去分布执行,即负载均衡或任务分发。
以上述基于Web的三层结构为例,首先在Web层,绝大多数的Web服务器都具有群集(Cluster)的功能,如Apache群集。这样,就可以将大量的HTTP请求均衡地分配到一个群集服务器上去执行。
多服务器协作(群集)有很多模式,总的来讲,一般可分为以下几类:
■ 对等模式;
■ 主从模式(Master/Slave);
■ N+1。
以下我们分别介绍这两种模式。
● 对等模式
对等模式的服务器集群中,每一台服务器的地位与作用都是完全相同的,它们之间没有主次关系,也没有职能不同的情况,如图6-12所示:
在对等模式中,对具体将任务分配到哪台服务器上执行的选择一般由其上一层的服务根据某种算法与规则来决定,比较常用的规则有以下四种。
(1)Round-Robin:这即是指上一层服务器将任务按照服务器1,服务器2,……,服务器n,然后再回到服务器1的首尾相接的环的顺序依次分配。该算法中,每次上一层服务器只需要记得最后一次被分配任务的集群服务器的顺序号即可。
(2)随机算法:采用随机数算法(如Rand函数),从N个服务器中每次任选一个服务器。
(3)优先级:对集群服务器动态设定优先级:即最开始时,大家的优先级都是一样的,当给某一台服务器分配一个任务后,其优先级就减少一级。以后再分配任务时,就在优先级最高的一组集群服务器中按照其他规则选择一个。
(4)综合算法:即对以上算法的综合。很明显,优先级算法需要和其他算法结合才可使用。
对等模式主要用于负载均衡的需求,其大多用于自开发应用中,最大的优势是上一层服务器可自行选择需要的服务器。
● 主从模式(Master/Slave)
在主从模式的服务器集群模式中,有一台服务器为主服务器,其他的服务器则为从服务器,其地位与作用可能都有不同,如图6-13所示:
主服务器的主要任务是按照某种规则分配任务给其他从服务器,这些规则可能是有两个目标:
(1)为了实现负载均衡;
(2)为了实现将不同类型的任务分给不同的服务器去执行。
值得说明的是,在很多情况下,集群主服务器本身也可以是一个从服务器。
对目标2,我们可以以6.2.3节2.中那个“三层C/S架构”的门户网站为例来说明。假如在代理层,有两个服务器,服务器1主要完成与企业数据库 交互的任务,服务器2主要通过SOAP协议与另一个应用服务器交互;则这两个服务器组成的集群如图6-14所示,其中,服务器1同时承担了主服务器与从服 务器的功能。
主从模式的集群在商业化产品中应用较广,如Apache集群就是采用这种方式来实现负载均衡的。
● N+1
N+1是一种介于对等模式与主从模式之间的一种集群模式。由于在各种文献中介绍很少,所以大多技术人员对这种模式不太熟悉。但该模式在实践中也有很重要的用途,有必要被软件设计人员所了解。
N+1模式主要用于众多的集群服务器在执行任务时分别都需要与数据库服务器或磁盘存储(I/O)交互的情况,在这种情况下,可以设计只有一台服务器与数据库服务器与磁盘I/O交互(即N+1中的1),而其他服务器则完成一些内存操作为主的业务逻辑处理,如图6-15所示:
在N+1模式中,由于较耗时的数据库操作与I/O操作集中在一台服务器上异步执行,从而,其他服务器的响应速度大大提高。
之所以说N+1是对等与主从模式的结合是因为:在N+1模式中,对集群服务器的选择仍然是由上一层服务器根据某种规则决定的;同时,各种服务器的地位与任务基本相同。
是否采用N+1,主要看您所涉及的应用系统,其中该层的集群服务器的任务处理是否是以I/O与数据库操作为主。
以上几种集群模式,各有其优缺点,读者在实际的设计中,应该根据具体情况,选择合适的架构。
4. 同构系统聚合
在6.2.2节中所述SOA架构中,实践中经常会有一种设计,它是通过把多个相同或相容的服务结点连接起来以建立大的企业软件系统,成为同构系统聚 合的体系。聚合体系内的各服务结点通过共同的通信协议共享信息或视图。在聚合体系中,数据或消息从任何一个服务结点出发,总能找到一个途径到达另一个服务 结点。
很显然,聚合是一种特殊的多服务系统架构,建立在这种架构基础上的企业软件系统通常只需要一个统一的公共接口(interface),所以设计功能时,只需要考虑两个服务结点之间的交流即可。
一个新的服务结点如果要加入系统,只需要与系统中任何一个已经连接结点连接上即可。不难看出,这种架构中,如果一个服务结点断开,可能会导致其他服 务结点同时断开,如图6-16中服务结点9断开,会使结点10,结点11,结点12失去联络,因此,一般采用这种架构的多服务软件系统,都应该设计把断线 结点重新连接到系统的功能。
一些聊天室或网络上的公共会议系统,就是采用这种架构来实现的。
现在假设有多个聚合,我们在每一个聚合中选择一个主结点服务,然后把每个聚合当成一个结点,通过主服务结点将各个聚合连接起来,就形成了一个更加庞 大的系统,我们称这种扩展后的聚合为联邦体系结构。联邦体系结构中的每一个聚合也可能是一个单服务结点,但重要的是它们都是同构系统。因特网的网络体系本 身就是一个典型的联邦体系结构的例子。
5. 调度系统
任务调度系统是生产实践中较为特殊的一种软件系统结构。中心调度服务根据预先设定或动态产生的任务队列与优先级,根据某种调度策略,分配或执行各项任务。
最为典型的调度系统例子应该是操作系统设计中的进程调度,如我们熟悉的分时调度策略、实时调度策略等。但由于本书讨论的重点是应用软件系统设计、开 发与管理,因此本节介绍的调度系统,主要是指广泛应用于运行大型信息系统机构(如银行、电信、保险公司、信息服务提供商等)的这样一种软件系统:它将信息 系统每日正常运行所需要的任务,通过一般以称为作业的运载单位来包装(通常是一个进程),再通过统一的排程系统,按照一定的先后顺序,对作业进行任务调 度。
在应用架构上,任务调度系统一般分为三层,分别是调度管理器、调度应用服务器、调度执行代理。通过三层架构,实现了作业任务管理、作业任务调度、作 业任务执行三部分功能的分离。调度的基本功能包括任务调度所应该有的,例如管理作业间的依赖关系、配置时间点运行任务调度、作业失败自动重试、作业调度过 程中的监控,以及干预等功能。高级一点的功能也可以包含作业执行节点负载均衡,并发控制等。
严格来讲,上述任务调度系统应属于多服务系统,如调度管理器可能是一个提供了Java Web界面的三层C/S结构单服务系统,调度应用服务器与调度执行代理可以分别是一个采用集群结构的单服务系统,各单服务系统之间通过建立在TCP/IP协议之上的应用层协议进行通信。
任务调度系统的特点是,除了组成其系统架构本身的各个服务器本身的工作进程、逻辑与算法以外,它还在不断地调起其他的作业进程,也就是说,调度系统 本身并不直接帮助用户完成某项功能,只是有效地协调控制其他的用户自定义作业,以一定依赖关系、在指定的时间内完成超大数量的业务功能。这是笔者单独介绍 调度系统架构的原因。
6. 异构系统集成
企业有很多异构系统,可能是应用程序、通信协议、操作系统、数据库、体系结构等均不相同,每个异构系统本身可能是一个多层单服务体系,现在,把各异 构系统如6.2.3.5节同构系统聚合那样通过统一的通信协议连接起来,就形成了SOA架构中的另一个实例,称之为异构系统集成。
异构系统集成时,各个异构系统之间的连接可以通过两种典型方式来实现:
■ 第一种方式就是如同构系统聚合那样,采用两两连接的方式。则一个系统总是可以找到一条通路到达另一个系统,但正如同构聚合的缺点一样,一个系统 的失败可能导致对其他系统的连接受阻;并且,每个应用系统除了设计请求处理与回传的功能以外,还需要设计请求转发的接口,以保证所以系统的连通。假设各系 统之间的连接采用基于消息的协议,则对应了消息处理及消息转发的功能;
■ 第二种方式即是结合采用6.2.2节中介绍“企业数据交换总线”的架构模式,即所有的异构系统都先连接到“企业数据交换总线”上,由它统一负责 系统之间的通信与交流。需要指出的是,各异构系统与交换总线的连接,即可以是全自动操作,也可以是有人工参与的半自动方式,这一点与同构聚合是不同的。
7. 数据存放与访问
在信息系统中,还有一种需求便是对数据的存储与访问,这包括将企业数据保存在数据库中或磁盘文件中。如果数据量小,则没有什么问题,但对于海量数据 的存放与访问,则在软件架构设计中需要专门考虑。当然,对该问题,在存储领域内,也有相应的解决方案,如RAID,但那些方法与软件层面的解决方案目的与 作用均不相同。本书只介绍软件层面的策略与结构设计。
其实,对数据的存放,无非是两种策略:集中存放或分散存放;对数据的访问,也无非是串行访问或并行访问两种策略。由于数据的存放方式决定了哪种访问方式更有效,因此,本书下面仅以数据存放方式为依据来分类说明这方面的问题。
● 数据集中存放
这种模式很容易理解,即将数据都集中存放一个存储服务器上。该种模式除了适用于小数据量以外,其实,对大数据量(可能达不到海量,但其容量也是很可 观的)的存放,也是一个重要的模式。这主要依赖于我们对数据的使用方式。如果在应用中,数据在存储时总是局部小批量地增加,在访问时,总是局部小批量地获 取与修改,则该种模式是比较合适的。典型的例子便是各个行业的生产系统。如银行与电信的核心业务系统。
● 分散存放——数据共享
该模式中,数据被分布存储到不同的存储服务器上去,但这些存储服务器对应用服务器来言却是共享的,如图6-17所示:
● 分散存放——数据非共享
对客户数据,按照某种规则分布存储到不同的存储服务器上去,但这些存储对应用服务器不是共享的。在数据访问时,则由不同的应用服务器分别在不同的存 储服务器上并行进行访问,最后将结果合并返回。当然,这种模式首先要求在应用服务器一层是主从模式的集群,主服务器执行数据分散的规则,触发并行查询,并 合并结果,如图6-18所示:
对后两种分散存放的模式,都是为适用于大批量数据导入及大批量数据访问与获取的目标而设计的。例如,数据库厂商为满足数据仓库的需要设计其数据存储 与访问的架构,一般都是采用其中一种。如众所周知的ORACLE RAC则是采用共享磁盘方式的,而TeraData及GreenPlum等则采用后一种非共享磁盘的方式。
对集中与分散两种模式的选择,似乎较容易决定,但对于海量数据存储与访问,到底采用哪一种分散方式更有效呢?本书这里不便作出判断,但需要指出的 是,非共享的分散存储,更加接近于网格的思想,有助于在同样成本的情况下获取更高的性能对需要建设海量数据中心的企业,两种分散模式都是值得考虑的架构。