传统的管理信息系统(MIS)开发采用客户/服务器(CLIENT/SERVER)模式,从体系结构上讲,一般采用两层结构,即应用(客户层)和数据服务层。客户端(应用层)提供用户操作界面,接受数据输入,向数据服务层发出数据请求并接受返回的数据结果,根据业务逻辑进行相关的运算,向客户显示相关信息;数据服务层接受客户端的数据请求,做相关数据处理,并将数据集或数据处理返回客户端。
在现在一些系统中,由于客户机较多,访问量和数据传输量都较大。为解决相应的瓶颈以及出于安全因素等方面的考虑,往往采用中间件组成三层(多层)结构应用体系(在两层结构应用开发中,常常会编写一些存储过程放在数据库端以供客户端调用,这已经有点类似三层结构)。三层结构应用体系将业务逻辑放在应用服务层,应用服务层接受客户机的业务请求,根据请求访问数据库,做相关处理,将处理结果返回客户机。应用服务层从物理上和逻辑上都可以独立出来,客户机(层)不直接访问数据库服务器(层),而是访问应用服务器(层)。客户层发出的不再是数据请求而是业务(事务)请求。两层与三层结构应用体系的比较如图1所示。
a、两层结构
b、三层结构
图1 两层与三层结构应用体系比较
两层体系结构在实际应用中已暴露出一些问题。如:客户机直接(或通过存储过程)访问数据库,所有客户机均访问数据库,不利于安全控制,难以防止黑客的恶意攻击。同时,网络流量很大,易形成网络瓶颈。还会造成数据库访问瓶颈及数据库连接数过多,影响数据库的响应速度,降低系统性能。另外,两层应用体系结构还有维护、扩展方面的问题。相比之下,三层应用体系结构显示以下优点。
进程管理:通过对服务进程的管理,使得在正常情况下,能用尽量少的服务进程处理尽量多的请求,减少进程的启动/终止次数。在峰值情况下,控制服务进程的总数,使得服务器在设定的负载下工作,不被压跨。总之,通过中间件对服务进程的有效管理,可以使系统在额定的功率下稳定工作,当请求服务的数量超过了服务器的处理速度时,中间件会把请求排队进行缓冲。
保持和复用数据库连接:服务进程访问数据库都要和数据库建立连接,如打开和关闭数据库等。中间件通过采用长驻服务进程的手段,使得与数据库的连接被保持和复用,从而大大减少与数据库连接的次数和时间。
支持交易优先级:通过对交易优先级的支持,保证优先级高的交易能尽快得到响应。
将系统分为三层(或多层),业务逻辑放在应用服务层,软件的维护集中在应用服务层,客户端的维护就相对简单多了,有利于软件维护及系统管理。
将客户端与数据库隔离起来,客户端无权限直接访问数据库,有利于安全管理,可有效防止恶意攻击。还可以利用中间件的安全管理特性进一步加强权限控制管理。
三层结构应用中可划分出业务(事务)级权限,一种业务一个服务程序(Service),利用中间件的安全管理对其进行访问控制。数据库的权限只分为对表(或表中的列)的插入(Insert)、删除(Delete)、修改(Update)、查询(Select)权限,它属于数据库表级的权限,而实际应用中往往以业务(事务)为主线,也就要求对业务(事务)实现权限控制,三层结构应用可以方便地对客户端实现事务权限管理控制。业务(事务)级权限控制的引入丰富和方便了权限控制与管理,实际上两层应用体系结构中可通过存储过程类似地实现业务(事务)级权限控制,但采用三层应用体系结构实现业务(事务)级权限控制更加灵活、方便、实效。
若要提高系统性能、处理速度,可增加应用服务器,分担一部分应用服务工作即可,而原来的应用服务器几乎可以不动。
两层应用体系结构中客户机直接(或通过存储过程)访问数据库,会造成数据库访问瓶颈及网络瓶颈,从而降低了整个系统的性能。
三层应用体系结构中,应用服务层的引入有效地解决了网络瓶颈和数据库连接数过多引起数据库性能下降的问题。应用服务层往往有多台服务器,可有效地解决客户机访问服务层瓶颈。应用服务器与数据库服务器(物理距离很近)可方便地采用宽带网连接,不会产生与数据库服务层网络瓶颈。
原有性能较差的设备(微机、小型机)均可发挥作用。大量复杂计算的工作均可放在应用服务器上(可由多台小型机组成),对硬件要求不是很高,客户机只做用户输入与显示,原有微机即可。采用三层应用体系结构后整个系统性能有很大地提高,也不会造成原有系统资源浪费。
三层应用体系结构能更好地调整应用体系,还可利用中间件的特点来选择路由、平衡负载,提高整个系统的性能。
总的来说,三层应用体系结构使应用系统的性能、安全性、扩展性有了很大的提高,也方便了系统的维护和管理。
要组成三层应用体系结构少不了要求采用中间件。中间件可以说是开发服务程序和管理这些服务程序运行的工具,是三层体系结构中一个非常重要的部分,它直接关系到整个应用系统的好坏,甚至成功与失败。
现在市场上的中间件很多,有TUXEDO、CICS,有基于CORBA的VisiBroker、M3,还有面向对象的JavaBean,中间件的选用很大程度上要看其成熟度。电信计费营帐系统是直接面向用户的应用系统,只许成功,不许失败。浙江联通公司选用中间件TUXEDO,也是基于成熟度及性能/价格比等方面的考虑。
TUXEDO是BEA公司的非常成熟的产品,占有很大市场份额,它有以下特点:
(1)支持全局事务管理,支持X/Open规范,支持全局的两阶段提交。
(2)分布式应用管理,支持异构环境下的分布应用(如同一应用中有不同的数据库,多个数据源)。
(3)平衡负载。有多台机器做应用服务器时,系统可自动根据每个机器的负载情况决定服务程序在负载小的那一台机器上执行。
(4)进程管理。系统根据需要(客户端请求量)自动增加或减少每个Service的进程数(1个Service可启动n个相同的进程)。某个Service忙,则相应地增加(启动)其进程数;某个Service闲,则相应地减少(关闭)其进程数,从而减少该Service占用的系统资源(如:内存、数据库连接数等),使整个系统的Service最优化运行。
(5)优先级管理。可将Service根据优先级的不同赋权值,系统根据优先级权值将客户请求(Service)排队管理。
(6)路由管理。有多台机器做应用服务器时,用户可设定同一种事务(根据申请包中FML的某一个域)在不同的机器上执行。
(7)权限控制、安全管理。包括两个方面:①服务端控制,可限制用户对应用程序的启动、关闭,限制用户在应用中建立服务程序。②限制客户端对应用程序的访问。可由专门的Service做安全验证。
(8)丰富的通信方式。有同步调用、异步调用、管道通信、会话、广播、通知、队列、发布订阅等通信方式,能很好地满足应用开发的要求。
(9)可MP方式工作,多台应用服务器互相备份,实现其高可用性。
四、中间件在浙江联通计费营业帐务系统营业子系统中的实现
浙江联通计费营帐系统三层体系中客户端程序用C++BUILDER,服务端(应用服务层)程序用Pro*c开发,中间件采用Bea公司的TUXEDO,数据库采用ORACLE8。其体系结构如图2所示。
三层体系中客户端与服务端的通信是由TUXEDO的API函数实现,客户端由函数Tpinit与服务器建立连接,由函数Tpcall申请Service服务,再由相关的TUXEDO函数对数据解包。
数据传输采用TUXEDO提供的非常灵活的FML方式实现客户端与服务端的数据交换。
目前,浙江联通计费营帐系统中所有营业受理模块、除详细话单以外的查询模块均采用三层结构来实现。
营业模块包括开户、话费收缴、改号、换/补卡、套餐变更以及营业数据的查询等,营业模块是用得相当频繁得模块(有300台客户机要同时实现25种服务),在将来高峰时将达到500多台,所以在本系统中首先采用三层结构来实现前台各种业务受理工作。
在营业受理子系统中,根据前台业务的分类,我们将服务端的服务(SERVICE)分成三类:
1.公共服务函数:提供诸如操作员登录、操作员权限控制、两台清方式的第一次提交确认、欠费校验、黑名单校验等。
2.公共查询服务函数:应用ORACLE的动态SQL功能,完成客户端发出的各种查询请求。
3.各业务提交函数:完成客户端各个业务(开户、改号……)的提交确认。
根据这三类SERVICE的不同特点,需要三种不同的配置要求。
服务程序之所以采用一个公用模块(程序),是因为业务受理涉及面广,几乎涉及所有数据库表,若每一种业务都做一个服务程序,则要做很多个服务程序。程序开发和维护量很大,系统扩展、管理不方便。且运行性能也受到较大的影响,因为每个服务程序至少启动一个进程,而有些进程由于业务上的原因会很少利用(运用)却占用了系统资源(如:内存、数据库连接数等)。
2.如何既简单又统一的实现界面中控件与FML缓冲、FML缓冲与服务端的数据的一致和数据交换?
对于第一个问题,我们应用面向对象技术,定义了一个C++ Builder虚类SaleManBase,SaleManBase类抽象出了一般业务的流程,同时给继承实现类又留有不同业务的实现接口。
从上图可以看出,SaleManBase类抽象出了一个典型业务的流程,同时它又给每个具体流程留有灵活的接口实现,如上图的第3、4、6步骤。
应用SaleManBase类,一般简单的业务(例如:改号、换卡等)只须在派生类中重载1至2个方法,添加10几行代码即可完成一个前台业务界面的编程。极大减轻了前台编程人员的负担,同时也简化了前台程序的管理和标准化。
对于第二个问题,我们主要通过两个组件来解决;一个是FMLClient组件,用来实现前台界面与TUXEDO的FML缓冲之间的数据交换。一个是MemTable组件,用来实现界面上的数据敏感组件和FMLClient组件之间的接口。
MemTable组件与其他数据访问组件间的关系
这样,通过这两个组件,编程人员就可以很容易的实现前台界面控件与TUXEDO服务端的通讯了。
从上图可以看出MemTable组件在系统中与界面数据敏感控件之间的关系,在定义MemTable中的字段名字时,我们人为规定了其与FML缓存中字段名一致。同时,我们又在FMLClient中定义了一组从MemTable中根据字段名取数据,和向MemTable中设置数据的方法;通过FMLClient提供的这一组方法,编程人员可以非常方便的保持界面控件和服务端数据的一致。
客户端程序控制:从客户端进行业务受理必须输入密码(由用户设定)才能办理相关业务,如:用户资料更改、特服变更、改号、换卡等。
服务端程序控制:客户端传过来的SQL语句必须是合理有序的。服务程序(Service)
每个操作员的菜单都是由管理员授予的,因此,操作员对于未授权的菜单是看不到和不能操作的。
数据库控制:用户帐号被授权对脚色(ROLE)进行存取,操作元的帐号不是数据库系统实际帐号而是应用程序帐号。
TUXEDO控制:利用TUXEDO特性对客户端访问服务程序(Service)的权限进行控制,由专门的Service控制。
大型数据库应用系统开发采用中间件已成为趋势,出于系统之间的良好接口和开放性考虑,中间件应选用基于面向对象的中间件,现在中间件面向对象的标准有:CORBA、COM、JavaBean等,其中CORBA(Common Object Request Broker Architecture)已为大多数厂商所接受。基于公用的面向对象标准的中间件,可简化异构环境下分布处理的复杂程度。对于多种分布式软件(如交易管理、负载平衡、Web主页、传统计算等),中间件减少了应用软件开发商的负担,使他们可以在跨越客户挑选的硬件、操作系统、网络、数据库管理系统和对象模型上建造分布式应用软件。