贝贝花花包包店,精品555皮具,钱夹,皮夹

字体: | 推荐给好友 上一篇 | 下一篇

ACE技术论文集-第10章 通过服务配置器模式动态配置通信服务

发布: 2008-6-13 14:34 | 作者: Prashant Jain and D | 来源: 转载 | 查看: 171次

 
10.5 协作
 
图10-4描述下面的服务配置器模式三个阶段中的组件间协作:
 
 
图10-4 服务配置器模式的交互图
 
  • 服务配置:服务配置器通过调用Service的init方法来对其进行初始化。一旦Service被成功初始化,服务配置器将其增加到Service Repository;后者管理和控制所有的Service。
  • 服务处理:在被配置进系统后,Service执行其处理任务(也就是,为客户请求服务)。当Service的处理在执行时,服务配置器可以挂起和恢复Service。
  • 服务终止:一旦不再需要,服务配置器通过调用Service的fini挂钩方法来将其终止。该挂钩允许Service在终止前进行清理。一旦Service终止,服务配置器将其从Service Repository中移除。
 
10.6 效果
 
10.6.1 好处
 
服务配置器模式提供以下好处:
 
  • 集中式管理:该模式将一或多个服务合并进单一的管理单元中。通过自动完成通用的服务初始化和终止活动(比如打开和关闭文件、获取和释放锁,等等),这有助于开发的简化。此外,它还利用一组统一的配置管理操作(比如初始化挂起恢复终止)来使通信服务的管理集中化。
  • 增强模块性和复用:该模式通过使服务的实现与服务的配置去耦合而改善了通信服务的模块性和可复用性。此外,所有服务都有统一的接口,并通过它来进行配置,从而鼓励了复用、并简化了后续服务的开发。
  • 增强配置动态性:该模式使服务能够被动态地重配置,而不用修改、重编译,或静态地重新链接已有代码。此外,服务的重配置常常可以无需重启该服务、或其他与之驻留一处的服务就得以完成。
  • 增加调整和优化的机会:通过使服务功能与用于执行服务的并发策略去耦合,该模式增加了开发者可用的服务配置选择的范围。通过从一系列并发策略中进行选择,开发者可以适应性地调整看守的并发水平,以配合客户的需求和可用的OS处理资源。可选项包括在客户请求到达时派生线程或进程、或在服务创建时预先派生线程或进程,等等。
 
10.6.2 缺点
 
服务配置器模式有以下缺点:
 
  • 缺乏确定性:该模式导致在应用的服务被在运行时配置之前,难以确定该应用的行为。对于实时系统来说,这可能是成问题的,因为在与其他特定的服务一起运行时,动态配置的服务可能无法可预测地执行。例如,一个新配置的服务可能会消耗过多的CPU周期,从而饿死其他服务,并导致它们错过它们的最终期限。
  • 可*性降低:使用服务配置器模式的应用比静态配置的应用可能要更不可*,因为服务的特定配置可能会有害地影响服务的执行。例如,有毛病的服务可能会崩溃,从而破坏它与其他服务共享的状态信息。如果多个服务被配置成在同一进程中运行,这就会特别地成问题。
  • 增加开销:该模式增加了服务执行的额外的间接层次。例如,服务配置器首先初始化服务,并将其装载进Service Repository。这在时间紧急的应用中可能会带来过多的开销。此外,使用动态链接来实现服务配置器模式增加了方法调用和全局变量访问的额外的间接层次。
 
10.7 实现
 
服务配置器模式可以通过许多方式实现。这一部分解释实现该模式时所涉及的步骤和可选方案。表10-1中总结了这些步骤和可选方案。
 
步骤
常用可选方案
定义服务控制接口
  • 服务从抽象基类继承
  • 服务响应控制消息
定义服务仓库
  • 维护服务实现表
选择配置机制
  • 在命令行指定
  • 通过用户接口指定
  • 通过配置文件指定
确定服务执行机制
  • 反应式执行
  • 多线程主动对象
  • 多进程主动对象
表10-1 实现服务配置器模式所涉及的步骤
 
  • 定义服务控制接口:下面是服务必须支持的的基本接口,用以使服务配置器能够配置和控制服务:
 
      • 服务初始化:提供服务的入口,并执行服务的初始化。
      • 服务终止:终止服务的执行。
      • 服务挂起:暂时挂起服务的执行。
      • 服务恢复:恢复挂起服务的执行。
      • 服务信息:报告描述服务的信息(例如,端口号或服务名)。
 
定义服务控制接口有两种基本的方法,基于继承的基于消息的
 
      • 基于继承的:该方法使每个服务都从公共的基类继承。这是ACE Service Configurator构架[7]和Java applets所用的方法。它通过定义含有许多纯虚“挂钩”方法的抽象基类来工作,如下所示:
 
class Service
{
public:
// = Initialization and termination hooks.
virtual int init (int argc, char *argv[]) = 0;
virtual int fini (void) = 0;
 
// = Scheduling hooks.
virtual int suspend (void);
virtual int resume (void);
 
// = Informational hook.
virtual int info (char **, size_t) = 0;
};
 
init方法用作Service的入口。它被服务配置器用于初始化Service的执行。fini方法允许服务配置器终止Service的执行。suspend和resume方法是调度挂钩,由服务配置器用于挂起和恢复Service的执行。info方法允许服务配置器获取与Service相关的信息(比如它的名字和网络地址)。这些方法一起给出了服务配置器和由它管理的Service之间的统一约定。
 
      • 基于消息的:另一种控制通信服务的方法是编写每个Service,使之响应一组特定的消息。这使得开发者有可能将服务配置器集成进缺乏继承的非OO编程语言中(比如C或Ada83)。
Windows NT服务控制管理器(SCM)使用这种方案。每个Windows NT主机都拥有主SCM进程,通过向系统服务传递多种控制信息(比如PAUSE、RESUME和TERMINATE)来自动对其进行初始化和管理。每个SCM管理的服务的开发者都要负责编写代码来处理这些消息。
 
  • 定义服务仓库:Service Repository被用于维护所有的服务实现,比如对象、可执行程序,或是动态链接库(DLL)。当服务被配置进系统、或从中移除时,服务配置器使用Service Repository来对其进行访问。每个服务的当前状态(比如它是活动的还是挂起的)也在仓库中维护。服务配置器存储并访问在主内存、文件系统或内核(例如,它可以使用报告进程和线程状态的操作)中的Service Repository信息。
  • 选择配置机制:服务需要在执行前被配置。配置服务需要指定一些属性,这些属性指示服务实现(比如可执行程序或DLL)的位置,以及在运行时初始化服务所需的参数。这样的配置条件可以通过多种方式来指定(比如在命令行上、经由环境变量、通过用户接口,或是在配置文件中)。通过将服务属性和初始化参数合并在一处,集中式配置机制可以简化应用中服务的安装和管理。
  • 确定服务执行机制:已由服务配置器动态配置的服务可以使用反应式[4]和主动对象[8]方案的多种组合来执行。下面简要地检查这些可选方案:
 
      • 反应式执行:可为服务配置器和它配置的所有服务的执行使用单线程控制。
      • 多线程主动对象:该方法使动态配置的服务运行在服务配置器进程里它们自己的线程控制中。服务配置器可以“按需”派生新线程,或是在已有线程池中执行这些服务。
      • 多进程主动对象:该方法使动态配置的服务运行在它们自己的进程中。服务配置器可以“按需”派生新进程,或是在已有进程池中执行这些服务。
 
10.8 示例代码
 
下面的代码介绍一个用C++写成的服务配置器模式的例子。该例子聚焦于10.2.3中介绍的分布式时间服务的与配置有关的方面。此外,它还演示了其他模式(比如反应堆模式[4]、接受器[5]和连接器[6]模式)的使用,它们通常被用于开发通信服务和对象请求代理(Object Request Broker)。
在下面的例子中,图10-3所示的OMT类图中的Concrete Service类由Time Server类以及Clerk类来表示。这一部分中的C++代码实现Time Server和Clerk类。两个类都继承自Service,使得它们可被动态配置进应用中。此外,该方法使用基于显式动态链接[7] 和配置文件的配置机制来动态地配置分布式时间服务的事务员和服务器部分。服务执行机制则基于在单线程控制中的反应式事件处理模型。
下面的例子显示事务员组件可以怎样改变它用于计算本地系统时间的算法、而又影响服务配置器配置的其他组件的执行。一旦算法被修改,事务员组件就由服务配置器进行动态重配置。
下面所示的代码还包括main驱动函数,它提供任何基于服务配置器的应用的通用入口。使用ACE[7],该实现可运行在UNIX/POSIX和Win32平台上;ACE可通过WWW在http://www.cs.wustl.edu/~schmidt/ACE.html获取。
 
10.8.1 Time Server
 
Time Server使用Acceptor类来接受来自一或多个事务员的连接。Acceptor类使用接受器模式[5]来为所有来自事务员的连接创建处理器;这些事务员想要接收时间更新请求。该设计使Time Server的实现与它的配置去耦合,因此,开发者可以独立于Time Server的配置改变它的实现。这为改进时间服务器的实现提供了灵活性。
Time Server类继承自在10.7中定义的Service基类。这使得服务配置器能够动态地链接Timer Server,以及解除其链接。在将Time Server服务装载进Service Repository之前,服务配置器调用它的init挂钩。该方法执行Time Server特有的初始化代码。同样地,当服务不再被需要时,fini挂钩方法被服务配置器自动调用,以将其终止。
 
// The Clerk_Handler processes time requests
// from Clerks.
class Clerk_Handler :
public Svc_Handler
{
// This is identical to the Clerk_Handler
// defined in the second section.
};
 
class Time_Server : public Service
{
public:
// Initialize the service when linked dynamically.
virtual int init (int argc, char *argv[])
{
// Parse command line arguments to get
// port number to listen on.
parse_args (argc, argv);
 
// Set the connection acceptor endpoint into
// listen mode (using the Acceptor pattern).
acceptor_.open (port_);
 
// Register with the Reactor Singleton.
Reactor::instance ()->register_handler
(&acceptor_, ACCEPT_MASK);
}
 
// Terminate the service when dynamically unlinked.
virtual int fini (void)
{
// Close down the connection.
acceptor_.close ();
}
 
// Other methods (e.g., info(), suspend(), and
// resume()) omitted.
 
private:
// Parse command line arguments or those
// specified by the configuration file.
int parse_args (int argc, char *argv[]);
 
// Acceptor is a factory that accepts
// connections from Clerks and creates
// Clerk_Handlers.
Acceptoracceptor_;
 
// Port the Time Server listens on.
int port_;
};
 
注意服务配置器也可以分别通过调用Time Server的suspend和resume挂钩来将其挂起和恢复。

32/3<123>
 

评分:0

我来说两句

seccode