ACE 服务配置:静态服务 和 动态服务

来源:互联网 发布:淘宝客全店推广如何做 编辑:程序博客网 时间:2024/05/16 14:50

ACE允许运行时动态地配置服务和流,无论它们是静态地链接进用户程序中,还是其对象是从共享库中动态地加载,既可以配置服务(一个对象代表一个服务),也可以配置流(基于配置文件而非编译时期装配模块)。运行时配置的益处在于:

●      多种类型的服务可以链接进程序中,也可以从共享库中动态地加载,通过配置文件决定运行时需要激活哪些服务;

●      在服务初始化时传入不同的参数或指定专用的配置文件;

1.配置静态服务

静态服务是指服务类别代码已经链接进执行程序的服务。

可配置静态服务开发的重点:

1)        所有的服务类别都必须是从ACE_Service_Object派生出来的子类。ACE_Task是派生自ACE_Service_Object,而ACE_Svc_Handler又是ACE_Task的子类,因此ACE_Task和ACE_Svc_Handler常用于实现可配置的服务类别。

2)        每个服务类别都必须实现以下挂钩方法:

u       virtual intinit(int argc, ACE_TCHAR *argv[]);-服务实例初始化

u       virtual intfini(void);-服务实例关闭

u       virtual intinfo(ACE_TCHAR **str, size_t len);-可选,报告自身的信息

init()会在服务实例初始化时被调用,如果服务初始化成功应该返回0,否则返回-1,此时ACE会移除服务实例。在某个已成功加载的服务实例关闭时会调用fini()方法。

ACE把已知可配置的静态服务放在一个“内部仓库”中,每个静态服务必须通过ACE宏将一些簿记信息插入该仓库以便ACE配置器框架实例化这些服务类别:

     ACE_FACTORY_DEFINE(CLS, SERVICE_CLASS)定义服务工厂和

“tear-down”函数,CLS是程序/库用来声明导入/导出的标识符,

CLS=ACE_Local_Service表示是一个链接进程序的静态服务,不需要导出服务工厂函数。对于动态服务,应该指定为导出标识符。

     ACE_STATIC_SVC_DEFINE(SERVICE_VAR,NAME,TYPE,FACTORY,FLAGS,ACTIVE)义一个静态服务对象,其中包含需要向配置器框架仓库登记服务的全部信息:

SERVICE_VAR:静态对象变量。

NAME:静态服务的名称。

TYPE:登记服务对象的类型,一般对于服务都使用ACE_SVC_OBJ_T。

FACTORY:创建服务对象实例的工厂函数,一般表示为:

&ACE_SVC_NAME(SERVICE_CLASS)

FLAGS:指定实在服务对象关闭时如何处置与服务相关的对象,一般使用:DELETE_THIS | DELETE_OBJ

ACTIVE:1表示服务在程序启动时激活,不能传递任何参数;0表示服务将根据配置文件中指令进行初始化。

     ACE_STATIC_SVC_REQUIRE(SERVICE_VAR)表示要求服务配置器框架在程序启动时创建服务对象实例,并向ACE Service Configurator登记它。SERVICE_VAR就是被创建的服务对象。

     最后,我们需要在配置文件中如下定义静态服务配置:

static service_name [arguments]

service_name就是ACE_STATIC_SVC_DEFINE中定义的服务名称。后面是可选参数字串。

例:static HA_Status_Static_Service “-f statuc.ini”

     在程序中,首先需要使用宏ACE_STATIC_REGISTER(SERVICE_VAR)来登记服务对象,然后应该调用ACE_Service_Config::open()方法来实现服务处理,此时需要将主程序的命令行选项传给该方法,此方法的最后一个参数指定是否忽略静态服务,或者也可以通过以下命令行参数来控制ACE Service Configurator的行为:

服务配置器框架的命令行选项

选项

含义

-b

使程序成为看守daemon,使用了这个选项,进程会在读取配置文件之前看守化。当在POSIX系统上进行看守化时,当前目录会变更为/,所以调用者应该指定完整的包含路径的文件名,或执行chroot转到适当的目录。

-d

打开调试模式。如果调试模式已打开,ACE Service Configurator会在它的各种动作发生时记录日志消息,描述这些动作。

-f

指定一个服务配置文件。用以替换默认的svc.conf,可以指定多个文件。

-k

指定ACE分布式日志服务客户代理的端口信息

-y

启用静态服务,忽略ACE_Service_Config::open的第四个参数ignore_static_svcs.

-n

禁用静态服务,忽略ACE_Service_Config::open的第四个参数ignore_static_svcs.

-s

指定用于触发“重处理配置文件”的信号,Windows平台将忽略。

-S

指定要处理的一条服务指令串。指令串放在引号中,服务指令串用于替代配置文件中指定服务指令。

2. 配置动态服务

动态服务是指服务类别被放在了共享库中,动态服务可以通过服务指令移除、增加或替换服务。动态服务的开发重点:

     动态服务驻留在共享库DLL中,因此必须在声明服务类别时指定导出标识符。

②    动态服务仅需要定义服务工厂:ACE_FACTORY_DEFINE(CLS, SERVICE_NAME)

该宏会生成一个服务工厂函数_make_service_name(),并导出该函数。

     在配置文件中,如下编写服务指令:

dynamic identService_Object * lib-pathname:object-class[active] [parameters]

dynamic identService_Object * lib-pathname:factory-func() [active] [parameters]

其中:

-ident:服务的名称。

-Service_Object:表示这是一个服务。

-lib-pathname:提供服务类别的共享库。

-object-class:服务类别。

-factory-func:服务工厂函数,用于实例化服务对象。

-active:是否激活服务对象。

-parameters:可选参数字串。

3. 配置流

流配置指令:

stream static|dynamic [modules]

stream ident [modules]

modules:

{ [[service-specification] [service-specification…]] }

service-specification-模块服务配置规范:

dynamic ident Module * -动态加载流模块类别

dynamic ident STREAM * lib-pathname:object-name [active] [parameters] -动态加载流类别

4. 重新配置服务

为了让ACE程序重新处理在ACE_Service_Config::open()被调用时使用过的服务配置文件重新配置服务,有两种方式:

(1)在POSIX系统中,向进程发送SIGHUP信号或是程序运行时参数”-s”指定

的信号,要求程序必须正在运行Reactor反应器循环。

(2)程序自身可以调用ACE_Service_Config::reconfigurator()方法,这种方式很

适合Windows程序使用,用户可以定义一个事件并创建一个事件处理器登记到Reactor反应器,使用事件处理器回调来实现重配置。

此时,服务配置文件在重新初始化服务对象实例前应该使用remove service-name的指令来移除之前创建过的服务对象实例。

5. 使用XML配置服务和流

ACE将来采用XML服务配置文件,以前的服务配置方法将成为可选方法。

此时,需要在构建ACE时定义宏:#define ACE_HAS_XML_SVC_CONF

6. 不通过svc.conf配置文件来引导ACE配置服务

ACE_Service_Config提供以下方法实现直接配置服务:

u      static int process_directive(const ACE_TCHAR directive[])

u      static int process_file(const ACE_TCHAR file[])

u      static int remove(const ACE_TCHAR svc_name[])

u      static int suspend(const ACE_TCHAR svc_name[])

u      static int resume(const ACE_TCHAR svc_name[])

7. ACE提供类别ACE_Service_Manager管理所有登记在ACE_Service_Repository中的可配置服务,并允许客户端通过socket连接向其发送指令:

        -help:list services列出所有登记的服务

        -reconfigure:重配置所有登记的服务

        -直接发送服务配置指令,执行process directive

 

注意:如果服务对象是单体的对象,对于静态服务我们可以使用ACE_Singleton进行包装,但是对于从共享库中加载的动态服务类别这应当使用ACE_Unmanaged_Singleton<T,L>进行包装