ACE技术论文集-第1章 ACE自适配通信环境
发布: 2008-6-13 15:02 | 作者: Prashant Jain and D | 来源: 转载 | 查看: 683次
ACE组件目前正在若干研究[46]和商业环境[6, 38, 47]中被用于增强通信软件的配置灵活性、以及可在多种硬件和软件平台上高效而可移植地运行的通信软件的组件的复用。为演示ASX构架是怎样被用于实践的,这一部分考查目前正在使用ACE组件进行开发的两种商业应用的体系结构:分布式日志工具和用于电信交换设备的分布式监控系统。
调试分布式软件常常极具挑战性,因为诊断输出出现在不同窗口中和/或不同的远地主机系统上。因而,ACE提供了一个分布式日志工具,以简化调试和运行时跟踪。该工具目前被用于一个商业在线事务处理系统[14]中,为高速网络环境中的群集工作站和多处理器数据库服务器提供日志服务。
如图1-12所示,分布式日志工具允许运行在多个客户主机上的应用发送日志记录给运行在指定服务器主机上的服务器日志看守。这一部分聚焦于日志工具的服务器看守部分的体系结构和配置,它们基于ASX构架提供的Service Configurator和ACE_Reactor类属来实现。分布式日志工具的完整设计和实现在[10]中描述。

图1-12 分布式日志工具
服务器日志看守是一个并发的多服务看守,它同时处理接收自一或多个客户主机的日志记录。服务器日志看守的面向对象的设计被分解为若干模块化组件(在图1-13中显示),由它们执行一些良好定义的任务。应用特有的组件(Logging_Acceptor和Logging Handler)负责处理接收自客户的日志记录。面向连接的组件(Acceptor和Client_Handler)负责接受来自客户的连接请求和数据。最后,不依赖于应用的ASX构架组件(ACE_Reactor、Service Condigurator和IPC SAP类属)负责完成IPC、显式动态链接、事件多路分离、服务分派和并发控制。

图1-13 服务器日志看守中的类组件
Logging_Handler子类是一种参数化类型,负责处理从客户主机发往服务器日志看守的日志记录。它的通信机制可以通过SOCK SAP或TLI SAP包装来实例化如下:
class Logging_Handler : public Client_Handler <
#if defined (MT_SAFE_SOCKETS)
ACE_SOCK_Stream,
#else
ACE_TLI_Stream,
#endif /* MT_SAFE_SOCKETS */
ACE_INET_Addr>
{
/* ... */
};
Logging_Handler类继承自Event_Handler(间接经由Client_Handler),而不是Service Object,因为它不是被动态链接进服务器日志看守的。
当来自与特定的Logging_Handler相关联的客户主机的日志记录到达时,ACE_Reactor自动分派对象的handle_input方法。该方法格式化记录,并将其显示在一或多个输出设备上(比如图1-12中所示的打印机、持久存储和/或控制台设备)。
Logging_Acceptor子类也是一个参数化类型,它负责接受来自参与日志服务的客户主机的连接请求:
class Logging_Acceptor :
public Client_Acceptor
符号Logger指定服务名,用于安装和运行时在ACE_Service_Repository中标识相应的Service Object。Service Object * 是位于共享对象文件中的_alloc方法的返回类型,共享对象文件的路径由路径名./Logger.so指定。服务配置器构架定位此共享对象文件,并将其动态链接进日志看守的地址空间。服务路径还指定派生自Service Object的应用特有对象的名字。在此例中,_alloc函数被用于动态分配新的Logging_Acceptor对象。该行剩下的内容(”-p 7001”)表示一组应用特有的配置参数。这些参数作为argc/argv风格的命令行参数传递给服务的init方法。Logging_Acceptor类的init方法将”-p 7001”解释为端口号,服务器日志看守将在其上侦听客户的连接请求。
<, /DIV>
#if defined (MT_SAFE_SOCKETS)
ACE_SOCK_Acceptor,
#else
ACE_TLI_Acceptor,
#endif /* MT_SAFE_SOCKETS */
ACE_INET_Addr>
{
/* ... */
};
因为Logging_Acceptor继承自ACE_Service_Object(间接经由它的ACE_Acceptor基类),它可以通过服务器日志看守的svc.conf配置文件来在运行时动态地链接进服务器日志看守、并进行相关的操作。同样地,因为Logging_Acceptor间接继承自ACE_Event_Handler接口,当来自客户的连接请求到达时,它的handle_input方法将会被ACE_Reactor自动调用。当连接请求到达时,Logging_Acceptor子类分配一个Logging_Handler对象,并将这个对象登记到ACE_Reactor。
通过使连接建立功能和日志记录接收分离成图1-13所示的两种不同的类层次,显著地增强了分布式日志工具的模块性、可复用性和可配置性。这样的分离允许ACE_Acceptor类被复用于其他类型的面向连接服务。特别地,为提供完全不同的处理功能,只需要重新实现服务的ACE_Client_Handler部分的行为。而且,参数化类型的使用减轻了对某种特定类型的IPC机制的依赖。
ASX构架使用Service Configurator来将日志服务动态或静态配置进服务器日志看守。动态配置的服务可在运行时插入、修改或移除,从而改善了服务的灵活性和可扩展性。下面的svc.conf文件条目用于将日志服务动态地配置进服务器日志看守:
dynamic Logger Service_Object *
./Logger.so:_alloc() “-p 7001”

图1-14 分布式日志工具中的ACE组件
当看守一开始执行时,静态配置的服务总是可用的。例如,Service Manager是标准的Service Configurator构架组件,客户可用以获取活动看守服务的列表。下面的svc.conf文件中的条目用于在初始化过程中将Service Manager服务静态地配置进服务器日志看守中:
static ACE_Svc_Manager “-p 911”
为使static指令工作,实现ACE_Svc_Manager服务的对象代码必须与主看守驱动可执行程序静态地链接在一起。此外,ACE_Svc_Manager对象必须在动态配置发生前插入Service Repository(ACE_Service_Config构造器自动完成此工作)。由于这些限制,如果不首先从Service Repository中将其移除,静态配置的服务就不能在运行时重配置。
服务器日志看守的主驱动程序通过下面的代码实现:
int main (int argc, char *argv[])
{
ACE_Service_Config loggerd;
// Configure server logging daemon.
if (loggerd.open (argc, argv) == -1 )
return –1;
// Perform logging service.
loggerd.run_reactor_event_loop();
return 0;
}

图1-15 服务器日志看守的交互图
图1-15描述多种构架与相互协作、以提供日志服务的应用特有对象之间的运行时交互。看守配置在ACE_Service_Config::open方法中完成。该方法查询下面的svc.conf文件,它指定将被配置进看守的服务:
static ACE_Svc_manager –p 911
dynamic Logger Service_Object *
./Logger.so:_alloc() “-p 7001”
通过将指定的ACE_Service_Object插入ACE_Service_Repository,并在ACE_Reactor上登记服务对象处理器的ACE_Event_Handler部分,来对svc.conf文件中的每个服务配置条目进行处理。
当所有的配置活动完成时,上面所示的主驱动程序调用ACE_Service_Config的run_reactor_event_loop方法。该方法进入事件循环,持续地调用ACE_Reactor::handle_events服务分派方法。如图1-9所示,该分派函数阻塞并等待事件的发生(比如来自客户的连接请求或I/O)。在这些事件发生时,ACE_Reactor自动分派先前登记的事件处理器,以执行指定的应用特有服务。
ASX构架还响应触发看守运行时重配置的外部事件。无论何时正在执行的基于ASX的看守接收到预指定的外部事件(比如UNIX SIGHUP信号),就会执行上面所述的动态配置步骤。取决于svc.conf文件的已被更新的内容,服务可以被增加、挂起、恢复或从看守中移除。
ASX构架的动态重配置机制使得开发者无需进行大量的重新开发和安装工作,就可以修改服务器日志看守的功能或调谐性能。例如,调试日志服务的一个有问题的实现只需要动态地重安装一个功能等价的服务,在其中包含有额外的手段来帮助隔离错误行为的来源。注意无须修改、重编译、重链接或重启当前正在执行的服务器日志看守,就可完成此重安装过程。
图1-16演示专用分组交换机(PBX)电信交换监控系统的客户/服务器体系结构,该系统使用ASX构架组件[20]实现。在此分布式通信系统中,服务器经由高速通信链路接收并处理由一或多个与服务器相连的PBX产生的状态信息。服务器转换此状态信息,并将其通过网络转发给客户终端系统,再由后者以图形方式显示给终端用户。终端用户通常是超级用户,他们使用PBX状态信息来监控系统全体成员的性能,并预测资源的分配、以满足客户的需求。
与服务器相连的PBX设备由Device_Adapter ACE_Module控制。该ACE_Module使服务器的其余部分与PBX特有的通信特性相屏蔽。Device_Adapter ACE_Module的读端维护一组Device_Handler对象(每个PBX一个),它们负责将到来的设备事件解析并转换成规范的、不依赖于PBX的消息对象;这种对象在一种在[6]中描述的灵活的消息管理类之上构建。
在初始化之后,到来的规范消息对象被传递给Event_Analyzer ACE_Module的读端。该Module为服务器实现应用特有的功能。在Event_Analyzer中维护的一个内部寻址表被用于确定哪些客户应接收消息对象。在Event_Analyzer确定适当的目的地后,消息对象被转发给 Multicast_Router ACE_Module的读端。
Multicast_Router ACE_Module是一个可复用组件,它使应用特有的服务器代码的余下部分与客户/服务器交互的知识,以及对通信协议的特定选择屏蔽开。通过建立连接到Multicast_Router ACE_Module,客户预订接收服务器发布的事件。Multicast_Router ACE_Module的写端接受来自客户的连接请求,并创建分离的Client_Handler对象来管理每一个客户连接。该Client_Handler对象处理在服务器和与之相关联的客户之间所有的后继数据传输和控制操作。一旦客户与服务器连接上,客户就指明它希望监控的PBX事件的类型。从这一点开始,当Multicast_Router的读端接收到来自Event_Analyzer的消息对象时,它就自动将此消息多点发送给所有预订接收该消息对象中封装的特定类型的事件的客户。
<, /DIV>
图1-16 PBX应用的ASX组件
ACE_Service_Config对象被服务器用于控制在安装时静态配置、或在运行过程中动态配置的流模块组件的初始化和终止。ACE_Service_Config对象包含有ACE_Reactor事件多路分离器的实例,用于将到来的客户消息分派给适当的Client_Handler或Device_Handler事件处理器。自客户到达的控制消息沿着流的写端向下发送,开始是Multicast_Router,接着是从相互连接的流ACE_Module的写端到Device_Adapter,后者再将控制消息发送给适当的PBX设备。同样地,Reactor检测来自PBX设备的事件,从Device_Adapter ACE_Module开始,沿着流向上分派它们。
组成PBX服务器的ACE_Module可以在任何时候配置进服务器。ASX构架通过使用svc.conf配置脚本驱动的显式动态链接来提供这样的灵活性。下面的配置脚本指示哪些服务将被动态链接进服务器的地址空间:
stream Server_Stream dynamic
STREAM * /svcs/Server_Stream.so : _alloc()
{
dynamic Device_Adapter
Module * /svcs/DA.so:_alloc() "-p 2001"
dynamic Event_Analyzer
Module * /svcs/EA.so:_alloc()
dynamic Multicast_Router
Module * /svcs/MR.so:_alloc() "-p 2010"
}
该配置脚本指示各层次相关的服务被动态链接和推入Server Stream的顺序。在应用初始化过程中,Service Config类解析此配置脚本,并执行每一条目的指令。
Server Stream由三个动态配置进服务器的ACE_Module(Device_Router、Event_Analyzer,和Multicast_Router)组成。指定的共享对象文件被动态链接进服务器(如dynamic指令所指定的)。随后通过调用_alloc函数,Module对象的一个实例就被从共享对象库中提取出来。如下面所描述的,如果需要的话,这些模块可随后被更新和重新链接(例如,安装ACE_Module的更新版本),而无须完全终止执行中的PBX服务器。
将服务静态配置进通信软件应用有着许多缺点。例如,如果过多的服务被配置进应用的服务器端,并且有过多的活动客户同时访问这些服务,就有可能导致性能瓶颈。相反,将过多的服务配置进客户端也有可能导致性能瓶颈,因为客户常常运行在不那么强大的终端系统上。一般而言,要预先确定适当的应用服务的划分是困难的,因为处理特性和工作负载可能会随着时间而发生变化。因而,ASX构架的一个主要目标就是开发面向对象的服务配置机制,允许开发者将关于哪些服务运行在客户端,哪些运行在服务器端的决定推迟到开发周期的非常迟后的阶段(也就是,安装时或运行时)。
为了便利灵活的重配置,ASX构架提供的运行时控制环境使开发者能够在安装时静态地、或在运行过程中动态地变更他们的应用服务的配置。这样的机制是有用的,因为不同的OS/硬件平台和不同的网络特性常常需要不同的服务配置。例如,在一些配置中,服务器执行大多数工作,而在其他配置中,客户完成更多的工作。而且,在不同的环境下(比如可用的是多处理器服务器平台,还是高速网络),可能需要不同的终端系统配置。图1-17演示了在服务器的处理构成主要瓶颈时,怎样对在图1-16中所示的配置进行变更,以在分布式环境中高效地进行运作。
该重配置过程通过下面的脚本完成:
suspend Server_Stream
stream Server_Stream
{
remove Event_Analyzer
}
remote "-h all -p 911"
{
stream Server_Stream
{
dynamic Event_Analyzer
Module * /svcs/EA.so : _alloc()
}
}
resume Server_Stream

图1-17 PBX监控系统的重配置
这个新脚本通过从服务器的流中动态地解除ACE_Module的链接,并动态地将它们链接进每个客户的流中[20],将处理功能从服务器移到了客户。ASX构架替换了以前的使用特别技术的体系结构(比如参数传递和共享内存),以在服务器中的相关服务间交换消息。与前面的方法相对照,ASX构架提供的高度统一的ACE_Module互连机制极大地改善了可移植性和可配置性。
ACE自适配通信环境是由许多OO组件组成的工具包,它通过实施成功的设计模式和软件体系结构,帮助降低了分布式软件的复杂性。ACE将许多通用的与通信相关的功能(比如本地和远地IPC[4]、事件多路分离和服务处理器分派[14]、服务初始化[16, 17]、含有整体式和层次化服务的分布式应用[20]的配置机制、分布式日志[13],以及服务内部及服务间的并发)统一进可复用的OO组件和构架中。
ACE可在http://www.cs.wustl.edu/~schmidt/ACE.html自由获取。该发布含有源代码、文档,以及在圣路易斯的华盛顿大学开发的测试实例驱动程序。目前ACE正在许多公司中用于开发通信软件,其中包括Bellcore、西门子、DEC、摩托罗拉、爱立信、柯达,和McDonnell Douglas。ACE已被移植到Win32(也就是,Win95、WinNT、Win2K),大多数版本的UNIX(例如,SunOS 4.x和5.x、SGI IRIX、HP-UX、OSF/1、AIX、Linux和SCO),以及POSIX系统(比如VxWorks和MVS OpenEdition)。同时有C++[6]和Java[48]版本的ACE可用。
[1] F. P. Brooks, The Mythical Man-Month. Reading, MA: Addison-Wesley, 1975.
[2] S. J. Leffler, M. McKusick, M. Karels, and J. Quarterman, The Design and Implementation of the 4.3BSD UNIX Operating System. Addison-Wesley, 1989.
[3] S. Rago, UNIX System V Network Programming. Reading, MA: Addison-Wesley, 1993.
[4] D. C. Schmidt, T. H. Harrison, and E. Al-Shaer, “Object-Oriented Components for High-speed Network Programming,” in Proceedings of the 1st Conference on Object-Oriented Technologies and Systems, (Monterey, CA), USENIX, June 1995.
[5] G. Booch, Object Oriented Analysis and Design with Applications (2nd Edition). Redwood City, California: Benjamin/ Cummings, 1993.
[6] D. C. Schmidt, “ACE: an Object-Oriented Framework for Developing Distributed Applications,” in Proceedings of the 6th USENIX C++ Technical Conference, (Cambridge, Massachusetts), USENIX Association, April 1994.
[7] D.E.ComerandD.L.Stevens,Internetworking with TCP/IP Vol III: Client – Server Programming and Applications.Englewood Cliffs, NJ: Prentice Hall, 1992.
[8] W. R. Stevens, UNIX Network Programming, First Edition. Englewood Cliffs, NJ: Prentice Hall, 1990.
[9] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995.
[10] D. C. Schmidt, “Reactor: An Object Behavioral Pattern for Concurrent Event Demultiplexing and Event Handler Dispatching,” in Pattern Languages of Program Design (J. O. Coplien and D. C. Schmidt, eds.), Reading, MA: Addison-Wesley, 1995.
[11] R. G. Lavender and D. C. Schmidt, “Active Object: an Object Behavioral Pattern for Concurrent Programming,” in Pattern Languages of Program Design (J. O. Coplien, J. Vlissides, and N. Kerth, eds.), Reading, MA: Addison-Wesley, 1996.
[12] R. Johnson and B. Foote, “Designing Reusable Classes,” Journal of Object-Oriented Programming, vol. 1, pp. 22–35, June/July 1988.
[13] D. C. Schmidt, “The Reactor: An Object-Oriented Interface for Event-Driven UNIX I/O Multiplexing (Part 1 of 2),” C++ Report, vol. 5, February 1993.
[14] D. C. Schmidt, “The Object-Oriented Design and Implementation of the Reactor: A C++ Wrapper for UNIX I/O Multiplexing (Part 2 of 2),” C++ Report, vol. 5, September 1993.
[15] T. H. Harrison, D. C. Schmidt, and I. Pyarali, “Asynchronous Completion Token: an Object Behavioral Pattern for Efficient Asynchronous Event Handling,” in The 3rd Annual Conference on the Pattern Languagesof Programs (Washington University technical report#WUCS-97-07), (Monticello, Illinois), pp. 1–7, February 1997.
[16] D. C. Schmidt, “Design Patterns for Initializing Network Services: Introducing the Acceptor and Connector Patterns,” C++ Report, vol. 7, November/December 1995.
[17] D. C. Schmidt, “Connector: a Design Pattern for Actively Initializing Network Services,” C++ Report, vol. 8, January 1996.
[18] D. C. Schmidt, “Acceptor and Connector: Design Patterns for Initializing Communication Services,” in The 1st European Pattern Languages of Programming Conference (Washington University technical report #WUCS-97-07), July 1997.
[19] D. C. Schmidt, “IPC SAP: An Object-Oriented Interface to Interprocess Communication Services,” C++ Report, vol. 4, November/December 1992.
[20] D. C. Schmidt and T. Suda, “An Object-Oriented Framework for Dynamically Configuring Extensible Distributed Communication Systems,” IEE/BCS Distributed Systems Engineering Journal (Special Issue on Configurable Distributed Systems), vol. 2, pp. 280–293, December 1994.
[21] P. Jain and D. C. Schmidt, “Service Configurator: APattern for Dynamic Configuration and Reconfiguration of Communication Services,” in The 3rd Pattern Languagesof Programming Conference (Washington University technical report #WUCS-97- 07), February 1997.
[22] D. C. Schmidt, “An OO Encapsulation of Lightweight OS Concurrency Mechanisms in the ACE Toolkit,” Tech. Rep. WUCS-95-31, Washington University, St. Louis, September 1995.
[23] D. C. Schmidt and C. D. Cranor, “Half-Sync/Half-Async: an Architectural Pattern for Efficient and Well-structured Concurrent I/O,” in Pattern Languages of Program Design (J. O. Coplien, J. Vlissides, and N. Kerth, eds.), Reading, MA: Addison-Wesley, 1996.
[24] D. C. Schmidt and T. Harrison, “Double-Checked Locking – An Object Behavioral Pattern for Initializing and Accessing Thread-safe Objects Efficiently,” in The 3rd Pattern Languages of Programming Conference (Washington University technical report #WUCS-97-07), February 1997.
[25] Bjarne Stroustrup and Margret Ellis, The Annotated C++ Reference Manual. Addison-Wesley, 1990.
[26] I. Pyarali, T. H. Harrison, and D. C. Schmidt, “Design and Performance of an Object-Oriented Framework for High-Performance Electronic Medical Imaging,” USENIX Computing Systems, vol. 9, November/December 1996.
[27] R. Davis, Win32 Network Programming. Reading, MA: Addison-Wesley, 1996.
[28] D. L. Presotto and D. M. Ritchie, “Interprocess Communication in the Ninth Edition UNIX System,” UNIX Research SystemPapers, Tenth Edition, vol. 2, no. 8, pp. 523–530,1990.
[29] W. R. Stevens, Advanced Programming in the UNIX Environment. Reading, Massachusetts: Addison Wesley, 1992.
[30] R. Gingell, J. Moran, and W. Shannon, “Virtual Memory Architecture in SunOS,” in Proceedings of the Summer 1987 USENIX Technical Conference, (Phoenix, Arizona), 1987.
[31] J. Eykholt, S. Kleiman, S. Barton, R. Faulkner, A. Shivalingiah, M. Smith, D. Stein, J. Voll, M. Weeks, and D. Williams, “Beyond Multiprocessing... Multithreading the SunOS Kernel,” in Proceedings of the Summer USENIX Conference,(San Antonio, Texas), June 1992.
[32] IEEE, Threads Extension for Portable Operating Systems (Draft 10), February 1996.
[33] D. C. Schmidt, “Transparently Parameterizing Synchronization Mechanisms into a Concurrent Distributed Application,” C++ Report, vol. 6, July/August 1994. 24
[34] G. Booch and M. Vilot, “Simplifying the Booch Components,” C++ Report, vol. 5, June 1993.
[35] R. Gingell, M. Lee, X. Dang, and M. Weeks, “Shared Libraries in SunOS,” in Proceedingsof the Summer 1987 USENIXTechnical Conference, (Phoenix, Arizona), 1987.
[36] W. W. Ho and R. Olsson, “An Approach to Genuine Dynamic Linking,” Software: Practice and Experience, vol. 21, pp. 375–390, Apr. 1991.
[37] H. Custer, Inside Windows NT. Redmond, Washington: Microsoft Press, 1993.
[38] D. C. Schmidt and P. Stephenson, “Experiences Using Design Patterns to Evolve System Software Across Diverse OS Platforms,” in Proceedings of the 9th European Conference on Object-Oriented Programming, (Aarhus, Denmark), ACM, August 1995.
[39] D. Ritchie, “A Stream Input–Output System,” AT&TBell Labs Technical Journal, vol. 63, pp. 311–324, Oct. 1984.
[40] N. C. Hutchinson and L. L. Peterson, “The x-kernel: An Architecture for Implementing Network Protocols,” IEEE Transactions on Software Engineering, vol. 17, pp. 64–76, January 1991.
[41] J. M. Zweig, “The Conduit: a Communication Abstraction in C++,” in Proceedings of the 2nd USENIX C++ Conference, pp. 191–203, USENIX Association, April 1990.
[42] D. C. Schmidt and T. Suda, “Transport System Architecture Services for High-Performance Communications Systems,” IEEE Journal on Selected Areas in Communication, vol. 11, pp. 489–506, May 1993.
[43] D. C. Schmidt, B. Stiller, T. Suda, A. Tantawy, and M. Zitterbart, “Language Support for Flexible, Application-Tailored Protocol Configuration,” in Proceedings of the 18th Conference on Local Computer Networks, (Minneapolis, Minnesota), pp. 369–378, IEEE, Sept. 1993.
[44] A. McRae, “Hardware Profiling of Kernels,” in USENIX Winter Conference, (San Diego, CA), USENIX Association, Jan. 1993.
[45] S. Saxena, J. K. Peacock, F. Yang, V. Verma, and M. Krishnan, “Pitfalls in Multithreading SVR4 STREAMS and other Weightless Processes,” in Proceedings of the Winter USENIX Conference, (San Diego, CA), pp. 85–106, Jan. 1993.
[46] D. C. Schmidt, D. F. Box, and T. Suda, “ADAPTIVE: A Dynamically Assembled Protocol Transformation, Integration, and eValuation Environment,” Journal of Concurrency: Practice and Experience, vol. 5, pp. 269–286, June 1993.
[47] D. C. Schmidt, “A Family of Design Patterns for Application-level Gateways,” The Theory and Practice of Object Systems (Special Issue on Patterns and Pattern Languages), vol. 2, no. 1, 1996.
[48] P. Jain and D. Schmidt, “Experiences Converting a C++ Communication Software Framework to Java,” C++Report, vol. 9, January 1997.
