在本 “Spring Roo 简介” 系列文章的 第 1 部分 和 第 2 部分 中,我们 使用 Spring Roo 从头开始构建了一个功能完整的企业应用程序。在那时,我曾打算写一篇关于 Spring Roo 与 Google App Engine 平台即服务 (PaaS) 集成的文章。Spring Roo 支持可部署在 Google App Engine 上的 Web 应用程序的构建,但是因为存在一些问题和限制,使部署我们之前构建的应用程序比较困难。我于是决定将这篇文章推迟到 Spring Roo/Google App 集成支持有所改进之后。本文简单介绍了 Cloud Foundry(开放的平台即服务),以及如何使用它来部署示例应用程序。在讨论 Cloud Foundry 之前,让我们先花些时间了解一下 “平台即服务”。
什么是 platform as a service?
平台即服务 (PaaS) 是云计算层中的一层。其他的层还包括软件即服务 (SaaS) 和基础架构即服务 (IaaS)。PaaS 位于 SaaS 和 IaaS 之间,提供了基础架构的抽象,并提供了一个计算平台和一个解决方案堆栈。
图 1. 平台即服务:云计算架构的战略中心
PaaS 适合于业务和专业开发人员。不编写代码的业务开发人员可以使用像 WaveMaker 这样的平台来开发包含拖放组件的应用程序,而专业的开发人员可以使用像 Google App Engine 这样的平台构建和部署 Web 应用程序。PaaS 具有一些设施,可用这些设施来支持构建和交付 Web 应用程序与服务的端到端的生命周期。一些主要的 PaaS 提供商有 Google App Engine for Java™ and Python、Microsoft® Azure for .Net and Java 以及 Force.com。
直到 2010 年,PaaS 的发展速度都未赶上 SaaS 和 IaaS,可能是受已有 PaaS 解决方案的限制。那么,让我们先来看看已有的 PaaS 存在的一些问题,这些问题是下一代 PaaS 平台(比如 Cloud Foundry)应该解决的。
已有的 PaaS 解决方案存在的一些问题
- 供应商锁定(缺乏云的可移植性): 没有为开发人员或组织提供从一个云转到另一个云的选项。比如,如果一个开发人员选择了 Google App Engine,那么他们必须一直使用 Google App Engine,除非此应用程序通过 Google App Engine 控制台删除 Google App Engine,并且让现有应用程序按照新的云提供商的要求进行修改。而此应用程序之后必须部署在此处。
- 只可部署到公共云:大多数现有 PaaS 解决方案都以公共云为目标,这导致了很多企业都不打算转至 PaaS。目前,许多企业永远都不会转至公共云,而且它们也没有在现有基础架构上设置私有云或组合使用私有与公共云的选项。
- 滞后的思维方式: 开发人员必须更改在公共云上构建应用程序的思维方式。之前,Google App Engine 并未提供关系数据库的选项。应用程序必须针对 BigTable 进行编码,因此在构建开始之前,需要先在思维方式上有所转变,而且已经有了与之相关的学习曲线。开发人员可以在没有任何修改的情况下将应用程序 WAR 文件部署到云内。
- 对稀松框架的支持:目前,Java 程序员大都使用框架,而且几近 100% 的框架支持都会引入一些编写应用程序方面的难题。使用任何像 Spring 或 Struts 这样的常见框架,通过 Google App Engine 构建一个简单的应用程序,这常常需要使用一些技巧进行处理,然后才能使用该框架。
- 束缚于某个特定的环境:已有的 PaaS 解决方案多限制于特定的环境,比如 Java 和 Python 使用 BigTable 作为 Google App Engine 的后端,.Net 和 Java 要求对 Microsoft Azure 使用 SQL Azure 数据库,对 Amazon Beanstalk 使用 Java。 使用任何这些 PaaS 都只要求在该环境下能正常存在。
- 非开源:已有的 PaaS 解决方案没有一个是开源的,这就让开发人员很难衍生代码并添加对供社区分享的新特性的支持。Cloud Foundry 的一个引入注目的元素是它的开源特性,该特性使得组织之外的开发人员也能对其成功起到主要作用。
2011 – PaaS 之年
Gartner 说过 2011 将是 “平台即服务” 之年。这可归因于领先的企业软件提供商引入了大量新的 PaaS 产品。目前已发布的 PaaS 产品有 VMWare 的 Cloud Foundry、RedHat 的 OpenShift、CloudBees 和 DotCloud。(参阅 参考资料, 获得所有这些产品的更多信息。)这些新的 PaaS 产品不会局限于一种语言或框架。现在,PaaS 已经真正成为了一种能支持使用多种语言和框架构建应用程序的平台。像 Cloud Foundry 这样的 PaaS 产品则更上了一个台阶,因为它支持多个云,我们将在本文的稍候部分对此进行讨论。这些改变会迫使已有的 PaaS 解决方案也成为多框架的。接下来,我们将重点讨论 Cloud Foundry,其他的 PaaS 产品不在本文的讨论范围之内。
什么是 Cloud Foundry?
在 2011 年 4 月,VMWare 发布了一个开放的平台即服务项目,名为 Cloud Foundry。Cloud Foundry 是一种多语言、多框架、多应用服务和多个云的开源平台。它试图解决之前所列出的已有 PaaS 解决方案中存在的问题。开发人员或组织可以使用 Cloud Foundry 作为部署目标,即可部署到由 Cloud Foundry 提供的一个公共云,也可将它用作为一层,从而允许部署到所选择的云(公共云和私有云)。Cloud Foundry 有三个关键特性:
- 在所有层上的选择:一言以蔽之,Cloud Foundry 是一个 PaaS 提供选项。给开发人员提供的选择并不限于编程语言,而是可以应用于所有的层(服务和云)。 图 2 所示的图表是对 Cloud Foundry 的一个很好的描述。
图 2. Cloud Foundry 选择
在 图 2 中,可以看到此三角型所有三个顶点上的选择。第一个顶点面向的是语言/运行时和框架。目前,Cloud Foundry 支持 Java、Groovy、Scala、Ruby 和 Node.js 语言。面向这些语言的受支持框架包括 Rails3、Grails、Node、Sinatra、Lift 和 Spring。第二个顶点对应于应用程序服务,开箱即用的可用服务有 MySQL(关系数据库)、Redis(键值数据仓库)和 MongoDB(文档数据仓库)。不久的将来还会提供对 RabbitMQ 和其他服务的支持。Cloud Foundry 为开发人员提供了使用 SQL 或 NoSQL 数据库的选择。仅仅掌握 MySQL 和 Java 的开发人员不必学习任何新东西,即可使用现有知识构建一个应用程序或部署已有的应用程序。第三个顶点显示的是云的选择。Cloud Foundry 可部署在一个公共云上,比如 cloudfoundry.com 上目前可用的公共云,也可以将 Cloud Foundry 部署于 IaaS 上,比如 Amazon EC2。还可以将 Cloud Foundry 下载并部署到您组织的私有云上,开发人员甚至可以将 Cloud Foundry 安装到自己的笔记本上,将它用作微云或开发人员云。
- 开源:Cloud Foundry 是一个开源项目,可在 Github 上找到(参阅 参考资料)。开发人员可以衍生 Cloud Foundry 项目,添加对新特性的支持或修复现有问题,还可以对此项目提供自己的贡献。 一家称为 ActiveState 的公司已经在 Cloud Foundry 上构建了自己的面向 Python 和 Perl 的云平台(参阅 参考资料)。之所以能够这样做完全是因为 Cloud Foundry 是一个开源项目,开发人员可以向它添加更多的服务或语言支持。
- 云可移植性:由于 Cloud Foundry 是一个开源项目,开发人员或组织拥有按需要运行 Cloud Foundry 的自由。RightScale 显示 Cloud Foundry 可运行在 Amazon EC2(参见 参考资料)上。那些不希望使用默认 Cloud Foundry 公共云的人可转而使用 Cloud Foundry 提供的其他云。
开始使用 Cloud Foundry
Cloud Foundry 公共云是作为 http://www.cloudfoundry.com/ 处的一个免费服务提供的。此服务目前仍未测试版。尚未获得 Cloud Foundry 凭证的用户必须先 注册一个帐户 后才能开始使用 Cloud Foundry 公共云。而收到 Cloud Foundry 凭证通常需要几天的时间。公共云目前运行于 VMWare vSphere 云操作系统之上。要在收到凭证之前就开始使用,可以通过 下载并安装 Cloud Foundry 在一台机器上设立一个云。
收到 Cloud Foundry 凭证后,可采用三种方式与之进行交互。所有客户端都会与由 Cloud Foundry 公开的 REST API 交互。这些 REST Web 服务是一些简单的 HTTP 上的 json 有效负荷。
- VMC 命令行客户端:VMC 是一个 ruby gem,它通过命令行提供对 Cloud Foundry 的访问。可用它来部署使用各种语言创建的应用程序。从 http://rubygems.org/gems/vmc 下载它。
- Spring Source Tool Suite(Spring Eclipse IDE 或 STS):STTS 是第二种连接到 Cloud Foundry 的方式。STS 是一个基于 Eclipse 的 IDE,常常与很多 Spring 产品捆绑在一起。欲了解有关 STS 的更多信息,可以参考 refcard 发布的 on dzone。访问 Cloud Foundry 还需要安装一个插件。在这个 IDE 内,可以进行所有的构建、测试和向云的部署。这真酷!您可以从 SpringSource 团队的博客 更多地了解它。
- Spring Roo Cloud Foundry 附加组件:使用 Spring Roo Cloud Foundry 附加组件,应用程序可以直接在 Roo shell 内部署。对于 Roo shell 的热衷者,这意味着将可以从 Roo shell 内进行构建和部署。Roo shell 提供的另一个好处是 tab 完成。向命令添加几个字母,按下 tab 键,Roo shell 就会完成此命令。
现在,我们来探讨 Java 开发人员如何从 Roo shell 访问 Cloud Foundry。我们还会将前两篇文章中所创建的这个应用程序部署到 Cloud Foundry。
Spring Roo Cloud Foundry 集成
Spring Roo 以附加组件的格式提供了对 Cloud Foundry 的支持。附加组件是一种机制,Spring Roo 借此提供对新特性的支持。
前提条件
要用 Spring Roo 向 Cloud Foundry 部署一个应用程序,要遵循如下步骤:
- 如果未在您机器上安装 Spring Roo,请参考本系列文章的 第 1 部分 开始使用 Spring Roo。我使用的是最新版本的 Spring Roo 1.1.5.RELEASE。
- 下载会议应用程序的源代码,参见 下载。该应用程序与前两篇文章中介绍的是同一个应用程序。目前使用 HSQLDB 作为数据库。我们稍后会将此应用程序移植到 MySQL 数据库中。
在 Cloud Foundry 上部署简单的 HSQLDB 应用程序
开发环境就绪后,就可以部署这个 conference 应用程序了。所下载的会议应用程序使用 HSQLDB 作为其数据库。要将此应用程序部署到 Cloud Foundry,可以遵循如下步骤:
- 将 conference.zip 解压缩到一个适当位置。
- 从命令行转至 conference.zip 解压缩的位置。
- 通过在命令行键入 mvn clean install 构建这个项目。
- 在 conference 目录内,激发 Roo 命令来加载 shell。
- 在 Cloud Foundry 上部署此应用程序之前,安装这个 Cloud Foundry 附加组件, 它将提供用来在 Cloud Foundry 执行操作的命令。要安装此 Cloud Foundry 附加组件,可以在 Roo shell 上键入如下命令:
roo> pgp automatic trust roo> addon install bundle --bundleSymbolicName org.springframework.roo.addon.cloud.foundry;1.1.5.RELEASE
第一个命令告诉 Spring Roo 自动信任所有 pgp 键,以便安装所有必需的附加组件,避免逐个信任各个信任键。第二个命令安装 Cloud Foundry 附加组件的 1.1.5 RELEASE 版。这个命令需要一些时间才能完成,所以请耐心等待。
- 安装完此附加组件后,必须先登录到 Cloud Foundry 才能执行操作。要登录到 Cloud Foundry,可以在 Roo shell 上键入如下命令:
roo> cloud foundry login --email [email protected] --password ****** --cloudControllerUrl http://api.cloudfoundry.com
cloud foundry login 命令接受三个选项:email、password 和 cloudControllerUrl。这三者中,email 和 password 是强制性的。cloudControllerUrl 的值默认为 http://api.cloudfoundry.com 处的 Cloud Foundry 公共云。若要部署到微云或其他地方的云,指向其 URL 即可。
- 要查看用来访问 Cloud Foundry 的所有可用命令,只需键入 cloud foundry 并按下 tab 键,您就会看到所有命令。
roo> cloud foundry <Press Tab> cloud foundry bind cloud foundry clear cloud foundry create cloud foundry delete cloud foundry deploy cloud foundry files cloud foundry info cloud foundry list cloud foundry login cloud foundry map cloud foundry restart cloud foundry start cloud foundry stop cloud foundry unbind cloud foundry unmap cloud foundry update cloud foundry view
- 要查看与您的 Cloud Foundry 实例相关的信息, 可按如下所示键入 info 命令。这个命令将会显示有关内存使用、部署在 Cloud Foundry 上的应用程序的数量以及运行的服务数量的信息。它还会显示最大分配值,即最大内存为 2GB。
roo> cloud foundry info VMware's Cloud Application Platform For support visit [email protected] Target: http://api.cloudfoundry.com (0.999) User: [email protected] Usage: Memory (0MB of 2048MB total) Services (0 of 16 total) Apps (0 of 20 total)
- 接下来,通过键入 cloud foundry deploy 命令部署此应用程序。这个命令需要两个必需属性 appName 和 path。appName 属性代表的是应用程序的名称,而 path 属性代表的是 WAR 文件的路径。没有必要输入此路径,只需在 path 后按下 tab 键,Spring Roo 就会为您寻找该路径。此外,还有其他三种非强制属性:instances、memory 和 urls。默认情况下,只启动应用程序的一个实例,但是通过使用 instances 属性来指定实例,可以部署此应用程序的多个实例。分配给实例的默认内存大小为 256MB。要更改这个属性,在部署时,可以使用 memory 属性。URL 属性则可用来指定映射到此应用程序的 URL。默认情况下,URL 为 <Application Name>.cloudfoundry.com,在本例中,对于我们这个应用程序,URL 为 conference.cloudfoundry.com 。键入以下命令来部署这个会议应用程序
roo> cloud foundry deploy --appName conference --path /target/conference-0.1.0.BUILD-SNAPSHOT.war
path 属性的值可以是 CREATE,具体情况取决于项目是否使用 Maven 构建。如果项目已经构建,正如本例中所示的那样,那么就会看到 war 的路径。否则,将会看到 CREATE,它首先构建项目,然后部署该应用程序。
- 所部署的应用程序尚未启动。使用如下所示的命令可以启动此应用程序。
cloud foundry start app --appName conference
- 在 http://conference.cloudfoundry.com/ 可以查看运行中的应用程序。
转至产品:用 MySQL 数据库替代 HSQLDB
从 面向本地环境的 HSQLDB 转换到产品环境的 MySQL 数据库十分容易。首先,使用 Roo shell 将 persistence store 从 HSQLDB 改为 MySQL,然后使用 Cloud Foundry 附加组件创建一个 MySQL 服务并将此服务绑定到此应用程序。代码没有必要更改;唯一要更改的是配置。在机器上甚至没有必要提供 MySQL 数据库,因为测试可以直接在云内完成。Cloud Foundry 使用起来就像在本地的开发人员机器上进行开发那么轻便。
- 打开 Roo shell,并通过在 shell 上键入如下命令将永久性存储库从 HSQDB 更改到 MySQL。
persistence setup --database MYSQL --provider HIBERNATE
这个命令将会更新此 pom.xml、database.properties、persistence.xml 指向 MySQL 的相关配置。
- 打开另一个命令行并执行 root 文件夹内的 mvn clean install -Dmaven.test.skip=true。请注意我跳过了测试,因为在这个会议应用程序中,没有 MySQL 数据库。
- 构建成功后,应用程序也就准备好,可以进行部署了。但是,在部署之前,请先删除此应用程序,以便可以为我们的应用程序创建一个 MySQL 服务,并重新部署 一个新的应用程序。没有必要在每次更改时都删除此应用程序,因为还可以使用 update 命令更新部署。
cloud foundry delete app --appName conference
- 现在,我们将部署新创建的这个具有 MySQL 特定配置的 war。
cloud foundry deploy --appName conference --path /target/conference-0.1.0.BUILD- SNAPSHOT.war --memory 512MB
- 以上命令可部署这个应用程序,但应用程序实例尚未启动。所以,在启动此应用程序之前,我们需要创建一个 MySQL 服务并将它绑定到我们的服务。为了创建一个新服务,我们使用了 Cloud Foundry create service 命令,并为它提供 serviceName 和 serviceType。serviceType 可以是 MySQL、MongoDB 或 Redis。
cloud foundry create service --serviceName conference-db --serviceType mysql
服务创建之后,就可以通过使用 bind service 命令绑定服务。bind service 命令确保了 MySQL datasource 依赖关系在云内可得到满足。在云内,这又称为依赖注入。
cloud foundry bind service --appName conference --serviceName conference-db
我们还可以通过指定 create service 命令的 appName 属性来避免使用 bind service 命令。cloud foundry create service --serviceName conference-db --serviceType mysql --appName conference
- 现在,就可以使用 start 命令来启动这个会议应用程序了。在 http://conference.cloudfoundry.com/ 处可找到此应用程序。
cloud foundry start app --appName conference
- 最后,通过执行如下所示的 Cloud Foundry list apps 和 list services 命令来查看应用程序和服务列表。
roo> cloud foundry list apps ================================= Applications ================================= Name Status Instances Services URLs ---- ------ --------- -------- ---- conference STARTED 1 conference-db conference.cloudfoundry.com roo> cloud foundry list services ================== System Services =================== Service Version Description ------- ------- ----------- mongodb 1.8 MongoDB NoSQL store redis 2.2 Redis key-value store service mysql 5.1 MySQL database service = Provisioned Services = Name Service ---- ------- conference-db mysql
结束语
在 本文中,我定义了 Cloud Foundry 以及它与其他 PaaS 产品的不同之处。通过集成 Cloud Foundry 与 Spring Roo,可为开发人员提供从 Roo shell 构建和部署 Spring 应用程序的快速应用程序开发环境。本文还探讨了如何创建一个 MySQL 服务并将它绑定到某个应用程序。
在后续文章中,我们将了解 Cloud Foundry 其他服务,比如 Redis 和 MongoDB。