剖析Recipe
在Cloudify体系里面,Recipe的概念可以理解为对应用配置运行的一系列说明处方,通过这个Recipe处方可以控制应用的安装、启动、运行、监控、扩展,这所有的一切都无需调整应用的代码或者架构。
Recipe的一些基本概念:
name "jboss-service"
icon "jboss.jpg"
type "APP_SERVER"
numInstances 2
//other recipe body here
1.一个应用Application是由一组服务Services组成
2.一个应用Application
Recipe描述的应用Application的名称和它所依赖的服务Service
3.服务是服务集群的实例,这些服务集群作为应用中间件层服务,比如Web容器、数据库、应用服务器等
4.每个Service的安装,都会被Service管理和监控
5.每个Service
Recipe定义了如下内容:
- 通用信息: 服务名称、服务类型、服务实例数、服务图标名
- 计算需求:硬件与软件
- 生命周期事件定义:控制事件的一些脚本,这是最重要的一部分内容
- 自定义命令:控制自定义事件的脚本,并且可以被Cloudify shell调用
- 探针:监控服务配置、性能、可用性
- UI:描述在Cloudify的Web管理控制台中如何显示性能指标界面
Application
Recipe
Application
Recipe包括了对应用描述的Recipe文件和所有它所需要依赖的Service的Recipe文件。Cloudify将首先启动Application所依赖的Service,再启动Application本身,以下是一个Application
Recipe的样例:
application {
name="petclinic-mongo"
service {
name = "mongoConfig"
}
service {
name = "mongos"
dependsOn = ["mongoConfig",
"mongod"]
}
service {
name = "tomcat"
dependsOn = ["mongos"]
}
}
从上述Application
Recipe可以看出,定义了一个名称为petclinic-mongo的应用,并分别依赖mongod、mongoConfig、mongos、tomcat四个Service。
为了使Application变得更加灵活可配置,可以在Application应用级别创建一个属性文件,该文件命名格式如下:
ApplicationName-application.properties
一个典型的应用场景假设有一个myApp应用,同时需要Tomcat和MySQL,那么在myApp-application.properties中定义一个databasePort=3306,将被myApp应用中的所有Tomcat和MySQL集群实例共享,用户不需要到服务上下文读取或存储这个端口信息。
还有另外一个应用场景如下,假设如下:
myService-service.properties
serviceName="my1stService"
serviceIconName="my1stServiceIcon.jpg"
serviceStart="my1stService_start.groovy"
myApp-application.properties
serviceName="newServiceName"
serviceStart="newService_start.groovy"
在Application启动运行期间,application级别的配置将覆盖service的配置,即serviceName为newServiceName,serviceStart为newService_start.groovy,而serviceIconName依旧是my1stServiceIcon.jpg。另外,在CLI中执行命令时可以通过overrides标记显式要求覆盖,例如:install-application
-overrides myOtherPropertiesFile myApp
Service
Recipe
Service
Recipe包括了对服务自身的描述文件和一些额外的支持文件。在Service
Recipe的通用信息中,除了服务名称、图标和实例数外,必须明确服务类型,Cloudify支持的服务类型包括:WEB_SERVER、APP_SERVER、DATABASE、NOSQL_DB、MESSAGE_BUS、ESB_SERVER、LOAD_BALANCER、SECURITY_SERVER,一个样例如下:
service {
}
Service 隔离性服务水平协议SLA
Cloudify支持很多Service服务部署在相同的宿主机,这可以最大限度的利用在云端物理机的最佳性能,隔离性服务水平协议主要支持以下四种形式:
-
dedicated
(default) –宿主机只部署特定类型的服务,没有任何其他服务可以部署到这台宿主机。 -
global
– 该宿主机被所有服务所共享,多租户基于各自应用的容量表现其所满足的SLA。 -
appShared
– 相同类型的应用可以共享宿主机。 -
tenantShared
– 位于相同权限组的多租户可以共享宿主机。
以下列举一些样例:
service {
name "groovy"
type "WEB_SERVER"
elastic true
numInstances 2
maxAllowedInstances 2
//
define SLA requirements for each service instance with regards to
isolation from other services
//
if this is not defined - defaults to dedicated mode. which means
each service instance is insalled on a dedicated VM.
isolationSLA {
global { //
global - meaning each service instance can be installed on any VM
that answer the requirements below.
//
allowing services to share VM's. Note: VM's running management
process are not included.
instanceCpuCores 0
//
no CPU requirements, this way instances can be installed on the
same VM even if it has just one CPU(can also define 0.5 CPU
requirements and so on...)
instanceMemoryMB 128
//
each instance needs 128MB to be allocated for him on the
VM.
useManagement true //
Enables installing services/applications on the management
machines. Defaults to false.
}
}
}
还有一些SLA的例子可以定义在*-service.groovy文件中
isolationSLA {
appShared { //
services belonging to the same application may share
machines
instanceCpuCores 0
instanceMemoryMB 128
}
}
isolationSLA {
global { //
all services may share machines
instanceCpuCores 0
instanceMemoryMB 128
}
}
isolationSLA {
tenantShared { //
service belonging to the same authenticationGroup may share
machines
instanceCpuCores 0
instanceMemoryMB 128
}
}
如果没有对Isolation SLA进行定义,那么dedicated
isolation SLA将被使用,即服务实例不能共享machines。
另外一个很重要的特性是,Cloudify允许重用对服务特性的定义,即可以将某个标准的服务定义单独编写一个外部公用的groovy文件,然后由不同Service
Recipe描述文件加载读取。例如:
一个定义为可以在Web管理控制台进行显示性能指标的layout样式
userInterface.groovy如下:
userInterface {
metricGroups = [
metricGroup{
name = "process"
metrics = ["cpu",
"memory"]
}
]
widgetGroups = [
widgetGroup{
name ="cpu"
widgets = [
balanceGauge{metric = "cpu"},
barLineChart{metric = "cpu"}
]
},
widgetGroup {
name = "memory"
widgets = [
balanceGauge { metric = "memory"
},
barLineChart{ metric = "memory"
axisYUnit Unit.PERCENTAGE
}
]
}
]
}
那么Service
Recipe描述文件可以做如下定义引用:
service {
name "myService"
……
userInterface load("userInterface.groovy")
}