Tuxedo为用户开发应用程序提供了一个高性能、高稳定性的框架。用户可以在这个框架内做任意想做的工作。但是为了提高整个系统的性能和稳定性,也需要遵循一些基本原则。在本章中,我们把在帮助客户构建系统时积累的经验进行总结,系统整理出来,供客户设计应用系统时候参考。
负载均衡
包括负载均衡的概念,如何设置负载均衡,LOAD/NETLOAD,队列的优先级,MSSQ的使用,SPINCOUNT, CMPLIMT,负载均衡的例子
如何划分Tuxedo的Server和Service?
在Tuxedo中,Server可以理解成为Unix的一个进程,Service可以理解成为应用进程Server中的一个函数。在Tuxedo 7.1以后版本中增加了对线程的支持,Server可以理解成为线程,但是这无关大局,我们依然用上面的理解来讨论下面的问题。
用户可以任意划分Server和Service:既可以把所有的Service放在一个单一的Server中,也可以采用“一个Service一个Server”的方式。Tuxedo对此没有任何限制。如果一个Service可以理解成独��的工作单元,每个Service负责一个独立、完整的商业业务流程,那么我们可以讨论一下关于如何划分Server和Service来提高整个系统的性能和可管理性。
一个最基本的原则就是尽量将“类似的Service”捆绑在一个Server之内。所谓“类似的Service”是指这些函数有相似的大小、执行时间、复杂度或者功能(例如:都是查询数据库或者都是进行计算)。为什么要这样呢,我们来考虑一个极端的例子:假设一个Service A是完成非常简单工作的,它的平均执行时间是100毫秒。另一个Service B进行数据库的查询,它的执行时间可能长达20秒。如果将这两个Service捆绑在一起,会出现什么现象呢?大家知道,操作系统的基本调度单位是进程(或者线程)。在一个进程中的Service执行是串行的。Tuxedo把发往同一个Server的请求交易包放在同一个消息队列中。当Service B在执行的时候,Service A的请求包必须在队列里面等待20秒以上才可能被执行,虽然它的执行时间仅仅100毫秒。这显然是不能容忍和应该避免的。
实际上,用户在设计和开发应用程序的时候,并不能完全估计出每个Service的执行时间和频度。所以对Server和Service的划分是在应用程序开发完毕后进行调整的。调整的依据就是在系统测试的时候记录每个Service的执行时间和频度,然后根据这些数据来进行优化调整。好在Tuxedo对Server和Service的划分非常简单灵活,这些工作做起来工作量并不是很大。下面就是我们对在实际当中获得的经验的一些系统总结。
规则一:详细注释每个Service
这实际上是一个软件工程方面的规则。Tuxedo基于的模型是三层体系结构。将用户界面的开发和商业逻辑的开发分离开来了。在一个实际的项目中,一般需要两方面的开发人员,一部分开发人员负责用户界面的开发工作,这些人员最熟练的技巧往往是HTML、Java、Visual C++、Delphi、C++ Builder、Power Builder、Visual Basic等等。而另一部分开发人员负责商业逻辑的开发,这些人员最熟练的技巧往往是在Unix环境下的Oracle和C/C++。Tuxedo的Service是独立完整的商业逻辑的入口函数,所有的Service在Tuxedo中具有相同的声明结构。另外,大型的商业项目的Service往往几百个甚至上千个。为了整个项目的可管理性,应该对每个Service的开头进行注释,表明这个Service的入口和出口参数是什么,主要执行什么功能。一个推荐的方法是制作一个通用的Service注释模版,开发人员创建一个新的Service的时候不需要从头开始。一般来说,Service的注释模版可以列出如下的一些要点:
l 版本号码
l 该Service的名称
l 该Service实现的功能
l 该Service的基本算法
l 入口参数
l 出口参数
l 其它需要列出来的说明
规则二:区分Service的不同类型:Business和Data Access
在商业逻辑层中的Service可以进一步细分成负责完成商业逻辑的Business Service和负责数据访问的Data Access Service两种类型。
规则三:同一个Server内的Service都访问相同的资源
规则四:Request/Response类型的Service要和会话Service分开在不同的Server中
在Tuxedo中,一个Server要么支持Request/Response类型的Service,要么支持会话方式的Service,具体是在配置文件中*SERVER一节中CONV=Y或者N来决定。会话方式和Request/Response方式是两种互斥的通讯方式。Request / Response 方式效率比较高,是使用最频繁的通讯类型。Tpcall/tpacall/tpforward都是Request/Response类型的API。会话方式适合大量的数据传输,但是它的代价是效率的下降。所以这两种类型的Service要分开放在不同的Server里面。
规则五:执行时间相似的Service放在同一个Server里面
在一个典型的Tuxedo应用环境中,可能有成百上千的Service,这些Service的执行时间显然是不同的。对于单线程的Server来说,虽然它可能有多个Service,但是这些 Service的执行是串行的。如果某个Server拥有两个Service,A和B。A的执行时间是100ms,B的执行时间是1000ms,也就是说执行一次B的时间可以执行十次A。那么当B在执行的时候,可能会有十个A在队列里面等待。这种情况会急剧降低该Server处理Service的吞吐率。因为,很自然的一个原则是把执行时间相似的Service放在同一个Server里面。
规则六:具有相同执行频度的Service放在同一个Server里面
在一个典型的Tuxedo应用系统中,并不是所有的Service的执行频率都是相同的。可能一些Service被频繁的执行,而另外一些Service只是偶尔才被执行几次。
规则七:Service的命名要科学
在一个大型的Tuxedo系统中,Service的数目可能达到上千个。
规则八:避免死锁的情况发生
在Tuxedo中的死锁情况有两种,第一种是一个Server中的Service A去调用同在一个Server中的Service B。这种死锁发生的原因是,对于单线程的Server来说,它其中的Service是串行执行的。Service A去调用Service B的时候,Service A还没有执行完,它等待Service B的返回结果。 但是Service B不能执行,因为该Server还处于执行Service A的状态。最终导致Service A超时而出错。
第二种情况是两个Server中的Service互相调用。例如Server1和 Server2,Server1中的Service A去调用Server2中的Service X。同时Server2中的Service Y去调用Server1中的Service B。这种情况发生的死锁和第一种情况非常类似,都是因为进程只能串行实行Service导致的。
这两种死锁情况特别要注意避免。第一种情况是比较容易察觉的,但是第二种情况就不大容易察觉。
如何在Tuxedo中使用各种开发工具
在众多的Tuxedo应用系统中,服务器端平台的选择多半是Unix。这是因为Unix在用户心目中一直是高性能、高稳定性的象征。在Unix上的开发工具主要是C,比较单纯。但是Tuxedo前端的操作系统很多,有基于Unix的,有基于Windows平台的,有用户的还采用浏览器的方式。如果客户端是基于Unix的,主要的开发工具当然是C编译器。在Windows平台上,用户可以选择的开发工具比较多,主要有Visual C++、Visual Basic、Delphi、C++ Builder、PowerBuilder等等。关于如何使用这些开发工具和Tuxedo互连,成为用户关心的一个问题。这里进行总体阐述。
Tuxedo的客户端是免费的,它在Windows 95/98上只能运行客户端部分,不能运行服务器端部分。在WindowsNT/2000/XP上可以运行客户端和服务器端软件。Tuxedo的客户端比较简单,提供的方式是一些头文件*.h、动态库*.DLL和相关的连接库*.lib。