理解Recipe

部署应用前,必须对即将部署的动作进行recipe配置。例如,官网例子,recipe依赖单一的MongoDB服务实例和Tomcat服务实例;由于例子已做好配置,该recipe可以不做任何修改也可以进行下一步操作。当然,也可以对一些可选项修改,比如,recipe中配置的服务实例数量。

Anatomy(剖析) of a Recipe

Recipes是在不修改应用代码和架构的同时,对应用程序栈安装、启动、协调、监控的执行计划。部署文件和文件夹位于应用的recipe文件夹中,例如:<cloudifyRoot>/recipes/apps/petclinic-simple. 下面是例子PetClinic应用的recipe文件和文件夹目录列表:

  • 应用描述文件:petclinic-mongo-application.groovy
  • MongoDB recipe 文件夹
  • Tomcat recipe 文件夹

运行MongoDB和Tomcat所需要的文件,可以在对应的mongod和tomcat子文件夹中找到。下图是PetClinic application的recipe文件和文件夹目录结构:理解Recipe_第1张图片

图中表明, mongod service继承了mongod service in ../../../services/mongodb/mongod, 而 tomcatservice 继承了the tomcat service in ../../../services/mongodb/tomcat.

The Application Recipe

每一份recipe必须包括一个描述文件,用于描述它所需要的的服务(层)及其依赖关系。

例子PetClinic application包含两种services, 每项service包含了单一的service实例:

  • Tomcat (将该服务称之为:tomcat)
  • MongoDB (将该服务称之为:mongod)

以下为PetClinic application的应用描述文件的内容:

application

{ name="petclinic"

service {

name = "mongod"

}

service {

name = "tomcat"

dependsOn = ["mongod"]

}

}

从该文件中可发现以下信息:

  • 运行该应用所需要的服务名称。
  • tomcatservice 依赖于mongodservice; 因此tomcatservice 在mongodservice成功启动前不会启动。

The Service Recipe

每一项服务受制于其自己的service recipe,该recipe通常基于一个recipe 结构。每一个service文件夹包含服务需要的所有信息。以下为service recipe的文件和文件夹:

  • 一个服务描述文件(<service name>-service.groovy).
  • 可选的properties文件(<service name>.properties),该文件包含recipe可能用到的配置参数。
  • 所有指定的生命周期脚本文件, e.g.<service name>_install.groovy, <service name>_start.groovy, etc.
    例如,<service name>_install.groovy脚本通常将在服务安装过程中运行, 当然这需要在服务描述符文件lifecyclesection中的指定。 注:你可以为生命周期处理程序指定任何名称,只要你在对应的服务文件指定他们的确切名称。
  • 一个可选文件夹usmlib,用于放置自定义probes所需的所有jar文件。
    Cloudify是松散的,你可以按需配置Scripted Probes。同样,你也可以开发自己的Plugin Probes ,并将其加入该文件夹中的recipe。例如,PetClinic application 使用了Cloudify Mongo Plugin Probe cloudify-mongo-plugin.jar ,用于提取mongodservice细节信息, 同时监测其端口活性。
The Lifecycle Scripts(生命周期脚本)

在tomcat recipe文件夹的Groovy脚本中,你可以发现它们基本上都是是可以由任何的groovy或java代码编写的普通脚本。唯一不同的是Cloudify API((ServiceContext API)的使用。). API暴露了service运行的细节,因此一个服务可以定位并使用同一个应用中的其它服务的细节。例如,PetClinic application通过API将mongodservice 实例的端口暴露给应用的其它所用服务。

Getting the Service Binaries(获取服务程序)

服务的二进制文件(执行程序文件),例子中的Tomcat和MongoDB发布版上传到为服务实例提供的machines中是相当大的。因此,当提供machines时,recipes通过一个指定的repository(可能是任一的Http、Ftp或本地文件系统)获取,并不从recipe中上传。那样可提高Cloudify环境的性能和反应。在Groovy中内置了支持Apache Ant的AntBuilder,通过Antgettask获取程序二进制文件。

The MongoDB Recipe

MongoDB (mongod) Recipe 执行下步骤:

  • 基于它的实例ID和属性文件计算其端口,然后通知serviceContext API,以便其他服务可以与它通信
  • 在提供的machine中下载、解压、安装 Mongo binaries
  • 启动 MongoDB Server process
  • 使用MongoLivenessDetector plugin 检测该项服务是否启动成功。
  • 收集度量标准(Active Read Clients, Active Write Client, etc.) 显示在Cloudify web管理控制台

Themongodservice 的描述在<cloudify root>/recipes/apps/petclinic/mongod/mongod-service.groovy.

The Tomcat Recipe

Tomcat Recipe执行下步骤:

  • 在提供的machine中下载、解压、安装Tomcat binaries
  • 配置Tomcat HTTP Port并开启remote JMX
  • 启动 Tomcat process (using the bin/catalina script)
  • 通过使用PortLivnessDetector plugin检查8080端口来检测server 是否启动成功
  • 通过JMX Monitoring plugin监测Tomcat的性能

The tomcat service 描述文件是<cloudify root>/recipes/apps/petclinic/tomcat/tomcat-service.groovy.

Configuringtomcatwith themongodport(mongod被Tomcat可用)

在例子中,我们使用ServiceContext API 和其 k/v 存储机制,用于分享mongod服务实例 (host address and port) 细节给tomcat服务实例。

首先, MongoDB recipe 暴露mongod服务实例细节如下:

// In <cloudify root>/recipes/apps/petclinic/mongod/mongod_install.groovy

import com.gigaspaces.cloudify.dsl.context.ServiceContextFactory

// ...

// Getting the mongod service instance ID

instanceID = serviceContext.getInstanceId()

// Calculating the mongod port and storing it in the serviceContext for later use

// (by the service and by other services).

serviceContext.attributes.thisInstance["port"] = config.basePort+instanceID

// ...

然后,Tomcat recipe 检索这些细节如下:

import com.gigaspaces.cloudify.dsl.context.ServiceContextFactory

// ...

// Waiting for the mongos service for 20 seconds

mongoService = serviceContext.waitForService(config.mongoService, 20, TimeUnit.SECONDS)

 

// Waiting for the mongod service instance for 60 seconds (In this case,

mongoInstances = mongoService.waitForInstances(mongoService.numberOfPlannedInstances, 60, TimeUnit.SECONDS)

// Retrieving the mongod host address.

// Note that the mongoInstances array is zero based.

def mongoServiceHost = mongoInstances[0].hostAddress

 

// Retrieving the mongod port

// Note that the mongoServiceInstances array is one based.

def mongoServiceInstances=serviceContext.attributes.mongod.instances

mongoServicePort=mongoServiceInstances[1].port

这个工作完成后,tomcat服务实例知道了mongod服务实例的主机地址和端口,即可以与之通信了。

你可能感兴趣的:(Cloudify,recipe)