Lifecycle Events Overview
Cloudify支持以下类型的生命周期事件:
- Application events — 内置events,在Cloudify shell提示符输入命令来调用。
- Service events —在service recipe中定义的事件,由ESM调用。
- Service instance events — 在service recipe中定义的最后要的生命周期事件,由ESM调用。
当一个生命周期事件被触发,事件需要的动作发生对应的事件处理脚本会运行。例如一个安装事件被ESM调用,对应的安装事件处理(定义在服务描述文件中)会执行。
已知的限制: 当start
事件反回,Cloudify将认为service 实例已经停止并且会试图重试。为了避免该行为,确保start脚本永久睡眠。
Application Events
Application events 是Cloudify内置的,当前不能在应用recipe中自定义。它们是由Cloudify shell提示符输入命令来调用的。通常用于执行各各任务,如,将recipes拷贝到管理machines中,然后触发相应的内置应用事件。
存在两种application events:
- Application install –用于安装应用,在 Cloudify shell prompt中输入:
install-application
<applicationName>
。这个命令提供应用所需要的服务,启动服务以满足应用的依赖关系,然后安装这个应用。 - Application uninstall – 卸载应用,在Cloudify shell prompt, 输入:
uninstall-application
<applicationName>。
这个命令用于停止和移除应用、应用依赖的所有服务、Cloudify agents,并关闭服务所运行的machine。
Service Events
服务事件在服务recipe中自定义。它们被ESM触发。这些事件对于服务实例启动前,或者在移除最后一项服务实例后关闭集群前,执行任务是非常有用的。它们能够运行在所有的或指定的服务实例上。
下图为服务事件图:
Service Instance Events
服务实例事件可以在服务recipe中自定义。他们被ESM触发。
下图为主要的服务实例事件生命周期。
Lifecycle Event Handlers(生命周期事件处理程序)
生命周期事件处理程序被定义在服务描述文件的lifecycle
section。他们可以被定义在一个与服务recipe同文件夹的外部文件中(支持的格式包括:Groovy scripts, Windows batch files, or *nix shell scripts),或者是一个内敛闭包(当代码很短的时候非常有用)。可以使用通过一个外部脚本文件来运行其它语言来编写脚本,并通过环境变量来提供其上下文。以下是一个事件处理程序可以分配的完整生命周期事件的序列:
preServiceStart
init
preInstall
install
postInstall
preStart
start
startDetection
locator
postStart
preStop
stop
postStop
shutdown
preServiceStop
以下为一个 lifecycle
section示例,为生命周期事件分配了事件处理程序。
lifecycle{
init "mysql_install.groovy"
start "mysql_start.groovy"
postStart "mysql_poststart.groovy"
preStop "mysql_preStop.groovy"
}
在某些情况下,一份recipe可能需要运行各种操作系统之上。以下一个lifecycle
section 展示了为生命周期事件分配不同操作系统的事件件处理程序。
lifecycle{
init "tomcat_install.groovy"
start ([
"Win.*" : "tomcat_run.bat",
"Linux" : "tomcat_run.sh",
"Mac.*" : "tomcat_run.sh"
])
preStop ([
"Win.*" : "tomcat_stop.bat",
"Linux" : "tomcat_stop.sh",
"Mac.*" : "tomcat_stop.sh"
])
}
Process Locator Events
Cloudify的过程监控、活性检测、停止事件,使用进程ids来执行它们的函数。默认情况下, Cloudify通过扫描进程树来收集process ids。 进程树由service recipe启动,用于放置所有的叶子进程(leaf processes,这样的进程不再产生新的进程)。
定位器事件程序 (locator
) 在 startDetection
事件后被触发,允许你重写Cloudify收集的默认process ids列表。通过在服务recipe的lifecycle section中定义定位器程序事件的事件处理程序。就可以写自己的代码来收集服务进程ids,并返回列表给Cloudify,用于监控。 这使得Cloudify可以监控服务的所有进程,并可以在所有相关联的服务已停止时,唯一标识该服务。
或者,如果你根本不想监控进程,定义一个关闭的进程定位器,返回 NO_PROCESS_LOCATORS
(这表示一个空的process ids列表).
例用,当你有一个服务进行频繁的产生和自相杀死进程,或者你不想对服务的活性进行监控时,这个定义很有效。
以下为一个例子 :
service {
name "simple-background"
icon "icon.png"
type "WEB_SERVER"
lifecycle {
start (["Win.*":"run.bat", "Linux":"run.sh"])
startDetection {
return ServiceUtils.isPortOccupied(8090)
}
locator {
NO_PROCESS_LOCATORS
}
}
}
如果没有在服务recipe中定义locator 关闭, Cloudify 会执行默认操作。
如果在服务recipe的 lifecycle section没有定义 start
事件处理程序, 从而machine会使用镜像的预配置来启动。 process locator 不会被触发. 因此,如果想监控服务的 processes,需要在服务recipe的monitors section中定义相关监控代码。
下面是服务recipe的 locator
closure 例子
service {
name "simple-background"
icon "icon.png"
type "WEB_SERVER"
lifecycle {
start (["Win.*":"run.bat", "Linux":"run.sh"])
startDetection {
return ServiceUtils.isPortOccupied(7777)
}
locator {
return ServiceUtils.ProcessUtils.getPidsWithMainClass("javaprocess.jar")
/* Uncomment to return pids for httpd and apache processes
return ServiceUtils.ProcessUtils.getPidsWithQuery("State.Name.re=httpd|apache") */
/* Uncomment to return pids for either Windows or *nix httpd processes
def winPids = ServiceUtils.ProcessUtils.getPidsWithName("httpd.exe")
def linuxPids = ServiceUtils.ProcessUtils.getPidsWithName("httpd")
List<Long> merge = []
merge.addAll(winPids)
merge.addAll(linuxPids)
return merge */
}
}
}
在事件处理程序内获取服务上下文(Retrieving the Service Context from within Event Handlers)
服务上下文可在事件处理脚本或在闭包中使用Service Context API来获取。以下例子是在Groovy event处理脚本中如何采用 ServiceContextFactory
来获取一个服务实例上下文的例子。
import org.cloudifysource.dsl.context.ServiceContextFactory;
def context = ServiceContextFactory.getServiceContext()
也可以在一个外部Groovy文件中使用ServiceContextFactory
,即不一定要在服务描述文件中使用。
要获得上下文的实例ID,只要简单的使用 context
变量,即可获得服务上下文的实例。如下:
def instanceId = context.instanceId
基于none-jvm可执行文件不能直接访问服务上下文。然而,一些上下文的信息可以通过以下环境变量:
- LOOKUPGROUPS
- LOOKUPLOCATORS
- USM_CLUSTER_NAME
- USM_APPLICATION_NAME
- USM_SERVICE_NAME
- USM_PU_UNIQUE_NAME
- USM_INSTANCE_ID
- USM_NUMBER_OF_INSTANCES
- USM_RUNNING_NUMBER
- USM_SERVICE_FILE_NAME
生命周期事件使用USM来调用外部事件处理程序,见下图:
Best Practices: Lifecycle Event Handlers
当定义生命周期事件处理程序时,最好的方法是分而治之。把任务分成简单的逻辑步骤,每个在下一步骤开始前完成,例如:
Event | Task Step |
preInstall | Get the service binaries |
install | Unzip the service binaries |
postInstall | Tweak configuration files as required |
preStart | Verify the installation files and folder structure |
start | Start the service |
postStart | Register service instances with a load balancer |
这种方法使配方更容易维护和故障排除。此外,通过设计事件外部处理程序脚本这种方式,可以在不同的应用程序重用他们的recipes。
来源:oschina
链接:https://my.oschina.net/u/140343/blog/123768