分布式多层体系结构
1、分布式多层应用模型
(1)J2EE 概述
互联网以及电子商务技术的普及和发展,推动着企业信息系统的构建和更新进程。为了缩短企业信息系统的设计和开发周期、降低构建企业信息系统的成本、在已有系统中对变化的商务规则迅速地做出反映,Sun公司制订了Java2 SDK Enterprise Edition(J2EE)规范,定义基于组件的方式设计、开发、组装和部署企业应用系统的各个组成部分。
J2EE规范定义了分布式多层应用系统模型、组件重用策略、一致化的安全模型以及灵活的事务控制策略等,使得独立软件提供商(ISV)能够以比以前更快的速度向市场推出具有用户适应性的客户解决方案。另外,平台独立、基于组件技术的J2EE解决方案不受软件产品类型和不同应用环境的制约。
在实际构建的企业信息系统中,需要根据J2EE规范定义的分布式多层应用模型将不同性质和用途的组件部署到不同类型的应用服务器中。J2EE规范根据企业信息系统各个组成部分在功能上的区别,将整个应用系统划分为客户层、中间层(其中可包括WEB层、业务层)和企业信息系统层三层结构,各个应用层分别配置在不同类型的应用服务器中。
(2)企业应用系统的各个逻辑层
l 客户层
客户层用于与企业信息系统的用户进行交互以及显示根据特定商务规则进行计算后的结果。基于J2EE规范的客户端可以是基于WEB的,也可以是不基于WEB的独立(Stand Alone)应用程序。 在基于WEB的J2EE客户端应用中,用户在客户端启动浏览器后,从WEB服务器中下载WEB层中的静态HTML页面或由JSP或Servlets动态生成的HTML页面。
在不基于WEB的J2EE客户端应用中,独立的客户端应用程序可以运行在一些基于网络的系统中,比如手持设备或汽车电话等。同样,这些独立的应用也可以运行在客户端的Java Applet中。这种类型的客户端应用程序可以在不经过WEB层的情况下直接访问部署在EJB容器(EJB Container)中的EJB组件。
l WEB层
J2EE规范定义的WEB层由JSP页面、基于WEB的Java Applets以及用于动态生成HTML页面的Servlets构成。这些基本元素在组装过程中通过打包来创建WEB组件。运行在WEB层中的WEB组件依赖WEB容器来支持诸如响应客户请求以及查询EJB组件等功能。
l 业务层
在基于J2EE规范构建的企业信息系统中,将解决或满足特定业务领域商务规则的代码构建成为业务层中的Enterprise JavaBean(EJB)组件。EJB组件可以完成从客户端应用程序中接收数据、按照商务规则对数据进行处理、将处理结果发送到企业信息系统层进行存储、从存储系统中检索数据以及将数据发送回客户端等功能。
部署和运行在业务层中的EJB组件依赖于EJB容器来管理诸如事务、生命期、状态转换、多线程及资源存储等。这样,由业务层和WEB层构成了多层分布式应用体系中的中间层。
l 集成层
集成层模式包含与JMS和JDBC有关的模式,使用消息、电子邮件、web 服务和其他技术,与各种企业系统连接和通信。
l 企业信息系统层
在企业应用系统的逻辑层划分中,企业信息系统层通常包括企业资源规划(ERP)系统、大型机事务处理(Mainframe Transaction Processing)系统、关系数据库系统(RDMS)及其它在构建J2EE分布式应用系统时已有的企业信息管理软件。
2、J2EE平台应用编程环境
按照对基于J2EE规范的企业应用系统逻辑层的划分,通常将分布式应用系统的编程环境划分为如下四种类型:
l EJB容器:EJB容器用于提供EJB组件的开发、部署和运行环境。
l WEB容器:WEB组件用于提供应用系统的显示逻辑,而WEB容器则提供适合于Servlet和JSP开发、部署和运行的环境。
l 客户应用容器:客户应用容器用于提供分布式应用系统的客户端运行环境,其本质上是J2SE。
l Applet容器:提供适合于Java Applet运行的浏览器运行环境。
3、Enterprise JavaBean规范的基本特征
在J2EE规范将企业应用系统划分的各逻辑层中,将封装商务规则的EJB组件部署在业务层中,用于根据客户端的服务请求进行业务数据的处理。EJB组件是基于分布式事务处理的企业级应用程序组件,其中包含处理业务数据的应用逻辑以及客户端调用EJB组件的商务方法获取服务的客户端接口。当一个遵循EJB规范开发的第三方EJB组件被集成到一个应用系统中时,不需要更改其实现代码或者重新编译。
(1)EJB组件类型
在EJB2.0规范中定义了三种类型的组件:会话组件(Session Bean)、实体组件(Entity Bean)和消息驱动组件(Message-Driven Bean)。
会话组件和实体组件的定义由Home接口、Remote接口和组件类构成。在EJB组件的Home接口中定义了创建、删除和定位EJB组件的方法;EJB组件的Remote接口用于定义组件能够提供的商务方法;EJB组件类则用于实现Home接口中定义的组件生命期方法以及Remote接口中定义的商务方法。
在 EJB 2.0 中,共定义了三种主要类型的企业 Bean:
l 会话 bean 是业务流程对象,其作用相当于执行动作的动词,例如,在两个银行帐户之间转移资金、执行采购订单批准流程、计算订单价格。
l 实体 bean 是数据对象,其作用相当于名词,通常代表实际生活中的对象,例如银行帐户、采购订单、员工、公司、厂商等。
ü 实体 bean 是内存对象,物理上映射到存储在底层关系数据库或遗留系统中的数据。持久化可以由开发人员手工控制(bean 管理的持久化),也可以由 BEA WebLogic Server 控制(容器管理的持久化)。
ü 会话 bean 通常“调用” 实体 bean 以实现其希望的操作,例如,处理采购订单(实体 bean)的采购订单批准路由器(会话 bean)。
l 消息驱动 Bean 是消息对象,设计目标旨在接收和转发消息,将消息从客户机传递给其他企业 JavaBean。例如,日志服务可以接收日志消息,并“调用” 会话 bean 执行实际的日志操作。
(2)会话组件
会话组件代表EJB组件与客户程序的一个短暂交互过程,其完成的功能可能是执行数据库读写操作或者是进行简单的数学计算等。
会话组件可以看成是瞬态的,其生命周期相对短暂,只有在客户程序与会话组件保持联系的过程中会话组件才具有生命力。如果客户程序结束会话过程,EJB容器将会话组件对象实例移出EJB容器中的组件实例池,该会话组件实例将失去生命力。另外,如果在客户程序与会话组件交互过程中EJB容器崩溃,那么用户必须重新创建一个新的会话组件对象实例来继续会话过程。
按照EJB2.0规范的定义,会话组件分为有状态(Stateful)和无状态(Stateless)两种类型。有状态会话组件中包含表示客户程序访问和更新数据的会话状态参数。会话状态参数用于记录会话组件引用的对象状态而不是在关系数据库中存储的数据资源。相对而言,在无状态会话组件中没有用于记录与特定客户程序相关联的状态参数,因此不能够记录客户程序的状态和保持客户程序在服务器端行为。
(3)实体组件
实体组件用于提供数据库中数据记录在EJB服务器中的对象类型视图。一个实体组件代表数据库表中一行数据记录。客户端应用程序对实体组件的访问等价于对EIS层中数据库的访问过程。在多客户应用的情况下,通过EJB容器的事务管理功能能够使多个客户进程以共享的方式访问同一个实体组件,进而保持组件对应数据库记录的一致性和完整性。实体组件的状态是持续的,只要数据库中的数据记录存在,实体组件创建后就一直存在于EJB容器中,即使EJB服务器崩溃,实体组件同样具有生命力。
与数据库记录在数据库表中的存在方式类似,在实体组件中定义了用于标识实体组件的主键(Primary Key)对象。该主键与标识数据库表记录的主键相对应,代表同一数据库记录的实体组件的主键值是相同的。客户端应用程序能够利用主键来定位EJB容器中的实体组件,进而定位实体组件表示的数据库记录。
按照实体组件的生命期管理方式,EJB规范将实体组件划分为组件管理持久性(Bean-Managed Persistence,BMP)和容器管理持久性(Container-Managed Persistence,CMP)两种类型。在组件部署过程中,由部署工具为容器管理持久性类型EJB组件的生命期方法编写组件状态转换代码,EJB容器调用这些方法实现组件的状态转换。相对而言,组件程序设计人员必须为组件管理持久性类型EJB组件编写控制组件的创建、删除、激活、关闭等生命期测量的SQL代码。
(4)消息驱动组件
消息驱动组件(Message Driven Bean)是EJB2.0规范中引入的新型组件,用于在EJB容器中提供一种响应外部事件消息的组件类型机制。
在引入消息驱动类型EJB组件之前,基于J2EE的分布式应用对于事件消息的处理方式是利用独立的Java事件处理程序来监听来自于客户端应用程序、EJB组件、JSP组件甚至是J2EE平台之外事件源发出的符合Java消息服务(Java Message Service,JMS)规范事件消息。引入消息驱动类型EJB组件后,部署在EJB容器中的消息驱动类型EJB组件利用组件中定义的OnMessage方法监听来自事件源的消息并做出反映,进而能够调用其它类型的组件来对消息进行响应。消息驱动类型EJB组件作为EJB容器中的事件监听器(Listener),可以在接收到来自JMS消息队列中的事件消息后由EJB容器来激活消息驱动组件对象实例。
消息驱动组件是服务器端的无状态类型组件。该类型的组件只有组件类定义,没有类似于会话组件和实体组件的Home接口和Remote接口。
4、EJB规范定义的开发者角色
EJB组件体系结构是基于J2EE规范构建的应用软件系统的主要部分。完整J2EE应用的核心内容是封装了商务逻辑的EJB组件。
按照EJB2.0规范的定义,基于EJB规范的分布式计算体系结构由六个角色组成,这六个角色可以是软件开发团队、系统软件供应商、应用软件集成商等,每个角色所完成的工作必须遵循EJB规范,以保证彼此之间的兼容性。这六个角色分别是:
(1)EJB组件开发者
EJB组件开发者(Enterprise Bean Provider)负责开发封装有商务规则的EJB组件。EJB组件开发者定义EJB组件的Home接口和Remote接口、编写组件类并且提供部署EJB组件的部署描述文件(Deployment Descriptor)。EJB组件开发者是商务应用开发领域的专家,不需要精通系统级编程方法以及系统级的组件事务管理、同步、安全性、分布式计算等细节。
(2)部署者
部署者(Deployer)负责将打包后的EJB组件部署到EJB服务器等应用环境中。部署者应根据EJB组件的部署描述文件中声明的对各种类型的资源,如数据库、安全性管理等的需求来配置EJB服务器来为组件提供服务。部署者是EJB应用环境方面的专家。
(3)应用组装者
应用组装者(Application Assembler)负责将各种类型的EJB组件组合成一个完整的应用系统,因此应用组装者必须明确待组装EJB组件的Home接口和Remote接口定义的详细内容。
(4)EJB服务器提供者
EJB服务器通常由操作系统开发商、中间件开发商或数据库开发商来提供。因此,EJB 服务器提供者(EJB Server Provider)是应用软件系统领域的专家,精通分布式系统管理、分布式对象管理及其它系统服务。
(5)EJB容器提供者
EJB 容器提供者(EJB Container Provider)是系统级的编程专家,其工作主要集中于开发可伸缩的,具有事务、交易和安全管理功能的集成在EJB服务器中的EJB容器。EJB容器提供者为EJB组件开发者提供了一组标准的API来访问EJB容器,使EJB组件开发者不需要了解EJB服务器中的各种技术细节就能够开发出部署在EJB容器中的EJB组件。
在实际应用中,通常假定EJB服务器提供者和EJB容器提供者来自同一软件开发商,因而没有定义EJB服务器提供者和EJB容器提供者之间的接口标准。
(6)系统管理员
系统管理员(System Administrator)负责为EJB服务器和EJB容器提供一个企业级的计算环境并利用EJB服务器和EJB容器提供的监测管理工具监测EJB组件的运行情况。
5、EJB容器
企业信息系统业务层中的EJB组件通常部署在被称为EJB容器的应用服务器中,由EJB容器提供EJB组件的状态管理、事务管理、线程管理、远程数据资源访问、连接管理和安全性管理等系统级服务。所有的EJB组件实例都运行在EJB容器中,由EJB容器控制着EJB组件的生命期。EJB组件可以被定制为提供安全和事务处理等各种系统级服务,但这些服务特性在本质上不属于EJB组件类,而是由部署EJB组件的容器来提供和实现的。
按照EJB规范编写的任何EJB组件均可以部署到任何一个与规范兼容的EJB容器中,可以根据应用系统的需要配置EJB容器来对组件的事务或安全性进行管理。在EJB组件部署过程中将业务逻辑的处理功能与底层的应用系统服务逻辑分开,使得EJB容器可以在运行时(Runtime)创建和管理EJB组件。
6、什么时候需要使用EJB技术
(1)你需要将商务逻辑组件与面向外界的 Internet 隔离开吗?
许多公司认为他们的应用软件,特别是构成商务逻辑的一些标准和数据结构,是极为重要的公司财产(例如,公司所拥有的分析应用工具构成了股票交易网站的一部分)。允许外人访问这些属于公司资产的原码和目标码将对公司产生极大的危害。因此,这些公司十分需要将商务逻辑置于一套安全防火墙后面(通常称为无戒备区,也称 DMZ)。
在这种情况下,分布式对象组件体系结构(例如 EJB 技术)允许你将有价值的公司资产隔离到 DMZ 以内,同时表示层代码可以访问 DMZ 内的 EJB 服务器。
这里我们假设表示层逻辑不如后台的商务逻辑重要。如果不是这样,那么这种方案的安全性就要下降,整个系统可能都需要置于 DMZ 之内。如果整个应用必须(或者能够)置于第二层防火墙后面,那么选择其它技术(如通过 Java Servlets 发出 JDBC 请求来直接访问数据库)就显得更合理。
(2)你需要不止一种类型的客户端访问共享数据吗?
通常,一个应用会有多种类型、需要访问相同信息的客户端。例如,一个应用可能会有供外部客户访问的基于 web 的 HTML 前端,以及供内部人员使用的更完整的应用前端。通常,这个问题是通过为同一应用编写两个共享相同数据源(数据库表)的版本来解决的。但是,这种方法效率不高,无论是从编程时间还是从同时发生多个数据库锁定时数据库的利用率来说。
EJB 技术的解决方案是将共享数据和商务逻辑集成到一套 EJB 组件中,以供不同类型的客户端(如 servlet/HTML 和 application)访问。EJB 组件控制着对后台数据的访问,并管理着当前事务以及数据库的内部锁定。通过去除应用中的重复代码,减少编写数据库控制逻辑的工作,这种方案降低了总的编程量。
在这个领域还有其它一些解决方案--比如,java 应用可以通过 HTTP 访问 java servlets,同时浏览器也可以通过 HTTP 访问 java servlets。这些解决方案的问题在于:如果 servlet 是用来在浏览器中显示信息的,它就必须包含一些表示层逻辑,这些表示层逻辑对于向另一个程序传递信息来说是多余的。因此,你最终不得不采用两套部分重复的 servlets 来处理两种情况。此外,HTTP 不是程序间通讯的效率最高的协议。你必须设计能通过 HTTP 管道进行程序间信息传递的数据格式--这通常或者是基于文本的格式,比如 XML(由接收端进行解析,由发送端生成),或者是基于对象的格式,比如 java 序列化。两种格式都需要大量的编程工作,它们都不如本地的 IIOP 速度快。
(3)你是否需要对共享数据同时进行读和写操作?
通常,"胖客户端"解决方案要求应用在数据库级别上管理对共享数据的访问。其结果是:处理数据库锁定与同步的方案非常复杂,若不考虑数据库锁定与同步问题又会失去数据的完整性。
EJB 技术能自动处理这些复杂的共享数据同步问题。正如前面提到的那样,EJB 组件控制着对后台数据的访问,并管理着当前事务和数据库的内部锁定。这不仅省去了编写数据库控制逻辑的工作量,同时也保证了数据的一致性与正确性,从而降低了总的编程量。
(4)你需要访问具备事务处理功能的多个异构数据源吗?
许多应用需要访问多个数据源。例如,一个应用程序可能既要访问来自中间层的 Oracle 数据库,又要通过中间件(如 MQSeries)访问 CICS、IMS 等大型主机系统。问题的关键是一些应用要求这种访问是完全事务化的,并且数据完整性在不同数据源间也能得到保证。例如,某个应用可能要求在处理用户的订购信息时,既要在 Oracle 数据库中存储详细的订购信息,同时又通过 MQSeries 在 CICS 系统中存储一份出货订单。无论是数据库更新或是 MQ 队列产生错误,整个事务都应被取消。
过去,构建这样的系统的唯一选择是采用事务监视器,例如 Encina、CICS、Tuxedo,它们使用非标准接口并需要用 COBOL、C、C++ 等语言进行开发。例如,高级版 WebSphere 中的 EJB 容器支持多个并发的事务,具备在多个 DB2 数据源间进行完整的事务提交及事务取消的能力,这些都是在一个完全支持二状态事务提交的环境中进行的。目前,WebSphere 对其它数据源(如 Oracle, MQSeries 和 CICS)只支持单状态的事务提交。企业版 WebSphere 中的 EJB 容器能对更多的数据源支持二状态的事务提交。
大多数容器正在支持各种数据源下的二状态事务提交方面不断完善。随着时间的推移,我们将在这一领域看到不断的进步。
(5)你需要能与 HTML 文档、servlets、JSP 文件、客户端登录安全性无缝集成的方法级对象安全性吗?
某些类型的应用由于其安全性限制,使得以前它们很难通过 java 应用来实现。例如,某些保险业的应用程序为了满足管理规定的要求,必须限制对客户数据的访问。直到 EJB 技术出现后,才能够限制特定用户访问某个对象或方法。在这之前,可实施的办法只有:在数据库级别上限制访问,并捕获在 JDBC 层次上抛出的错误;或者通过客户安全密码在应用层上限制访问。
EJB 技术可以在任何 EJB 组件或方法上实施方法级的安全策略。创建的用户和用户组可以被授予或禁止对任何 EJB 组件或方法的操作权。在 WebSphere 中,用户组可以被授予或禁止对 web 资源(servlets, JSP 文件和 HTML 页面)的访问权,用户的 ID 可以通过底层的安全机制被安全地从 web 资源传递到 EJB 组件。
(6)体系结构是否有标准化、轻量化、组件化的需要呢?
对于许多有远见的公司来说,关键问题是要实现平台、销售商和应用服务器设备间的相互独立。符合工业标准的 EJB 组件体系结构有助于实现这些目标。为 WebSphere 开发的 EJB 组件通常可以发布到其它类型的应用服务器上使用,反之亦然。尽管这一目标尚未完全实现,但它已成为许多客户选择的战略发展方向。从短期看,利用一些可能优于标准化的特性会更方便、更迅速,但从长远看标准化具有最大的好处。
你也应当考虑到越来越多的可选工具和 EJB 标准的优化实现手段,这些都是你无法从本地管理对象框架中获得的。由于大多数公司并不从事中间件业务,将注意力集中在与你的业务更直接相关的活动上会更有效。
(7)你需要多个服务器来满足系统的吞吐量和有效性需要吗?
胖客户端系统显然不能适应 web 系统可能拥有的成千上万个用户。软件发布方面的问题也要求给胖客户端减肥。Web 站点的24小时不间断运行特点也使得时间成为关键问题。但并不是每个人都需要24小时不间断运行,并能同时处理上万个用户的系统。你应当能设计这样的系统:在不增加开发和标准化难度的前提下,实现系统的伸缩性。
因此,你要设法使得编写的商务逻辑可以进行伸缩来满足这些需要。EJB 技术为构建这种具有高伸缩性、高利用率的系统提供了骨架。
7、分布式组件的含义
它是能够实现远程组件的分布式调用,但是我们在实际的设计中不会可以将不同的组件分布到不同的机器中,这样既有性能的问题,又有设计的复杂性的问题,只有在需要的时候才进行组件的分布布署。
理想的情况应该是将所有的组件布署到一个机器中,如果一台机器不能满足需要,可能需要考虑平台的水平扩展能力,通过负载均衡扩展系统的处理能力。