Tuxedo应用设计的经验
时间:2009-05-20 09:36
来源:dev2dev
作者:
点击:216次
Tuxedo为用户开发应用程序提供了一个高性能、高稳定性的框架。但是为了提高整个系统的性能和稳定性,也需要遵循一些基本原则。在本章中,我们把在帮助客户构建系统时积累的经验进行总结,系统整理出来,供客户设计应用系统时候参考。
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
注释模版,则没有固定的格式。用户可以自行设计,实用就行。下面给出一个参考模版,谨供参考。
Version Number:
|
Application Name(s):
|
Service Name:
|
Service Routine:
|
Source File Name:
|
Business or Data Access Service:
|
Resources Accessed:
|
Query or Update Service:
|
Request/Response or Conversational:
|
Routing Field:
|
Service Priority:
|
Service Load Factor:
|
Mean Input Buffer Size:
|
Mean returned buffer size
|
Mean Execution Time:
|
90% Execution Time
|
Mean Call Frequency Xact/hour:
|
Peak Call Frequency Xact/hour:
|
Constraints: e.g. only 10 instances of this service can exist
|
Services Called at Boot-Time:
|
Services Called at Run-Time:
|
Services Called at Shutdown:
|
Environment Variables:
|
Input Buffer Specification
|
Input Buffer Type:
|
Input Buffer Subtype:
|
Buffer Size
|
File/Structure
|
|
Output Buffer Specification
|
Output Buffer Type:
|
Output Buffer Subtype:
|
Buffer Size
|
File/Structure
|
规则二:区分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
。