内容


在 Bluemix 中实现基于微服务的架构,第 1 部分:使用 CF Apps 执行构建和部署

将应用程序分解为多个通过明确定义的 API 彼此通信的服务

Comments

微服务架构使您能够构建更加弹性和可扩展的云应用程序。应用程序分解为多个在需要时通过明确定义的 API 彼此通信的服务。在这个教程系列中,我们将展示如何在 IBM Bluemix™ 平台上使用 Cloud Foundry (CF) Apps 和 IBM Containers 实现基于微服务的应用程序。第 1 部分重点介绍 CF Apps。

我们的示例应用程序是使用 微服务架构模式 构建的,是一个销售眼镜框的简单的电子商务商店。示例应用程序仅用于演示目的,不代表产品级质量的代码。但是,它确实展示了一个探索微服务的简单代码基础。

运行示例应用程序获取代码

示例应用程序由两个微服务组成:

  • cat 管理产品目录
  • cart 管理每个浏览器会话的唯一购物车

客户端用户界面管理购物的 Web 用户界面。目前还没有用于购物、库存管理或帐户管理的微服务。所有这些服务都可在未来开发,而不会影响我们的实现方法。

在本教程中,我们将使用 CF Apps 构建我们基于微服务的购物应用程序。本系列后面的教程将展示如何使用 IBM Containers for Bluemix 构建同一个应用程序。

完成本教程所需的软件

每个微服务在 Python 中实现并使用 Flask 微框架。我选择了 Python 和 Flask 是因为它们拥有必要的构件包 (build pack) 和映像。如果您希望在从 git 存储库获取服务器和 UI 代码后修改它,Python 和 Node.js 很有用。

微服务简介

应用程序架构不断在演变,以满足用户需求和利用云计算。用户希望他们的应用程序可用在平板电脑、智能手机和浏览器中。这些应用程序需要处理触控和键盘/鼠标用户界面。对应用程序更新的部署频率比对传统套装软件的更新更高。因此,为桌面浏览器开发简单的单一 Web 应用程序已不再足够。

基于云的应用程序中正在应用分布式软件设计模式和 “系统之系统” 概念。微服务架构模式 指的是将一个应用程序或服务实现为一组独立的部件(“微服务”)。每个微服务具有有限的范围,它们可在需要时通过公开来供客户端使用的明确定义的 API 来扩展。

对于开发人员,微服务架构模式的优势包括:

  • 开发人员可单独管理版本和部署应用程序组件(微服务)。
  • 开发人员可以小型敏捷团队的形式处理单独的微服务。
  • 开发人员可应用包含持续发布、滚动升级和微服务 A/B 测试的 DevOps 文化。
  • 开发人员可专注于在交互的组件之间建立契约,因为微服务架构天生以 API 为中心,具有松散的耦合和高凝聚力。

API 网关:一种常见的微服务模式

API 网关模式 解决了微服务架构的基本问题,那就是基于微服务的应用程序的客户端如何访问各个服务:

试想一个向一个类似 Amazon 的电子商务商店提供用户体验的移动应用程序。我们假设该电子商务商店是使用微服务实现的。要显示一个产品页,移动应用程序将需要与多个微服务交互,比如:

  • 产品目录
  • 库存
  • 客户评论
  • 用户帐户
  • 购物车

每个微服务公开一个 API 端点,所以我们的移动应用程序将拥有呈现一个产品屏幕所需的多个端点。

现在,如果我们希望重构一个微服务,会发生什么?因为移动客户端直接与每个微服务通信,所以每次我们修改微服务的 API 时,移动客户端都必须更新。这会增加将更新推送到所有使用移动客户端的设备的复杂性。

API 网关模式解决了此复杂性:无需让移动客户端直接与每个微服务交互,可创建一个 API 网关。它充当着一种前端控制器形态 — 进入应用程序的单一逻辑点。

对于开发人员和架构师而言,API 网关模式提供了以下优势:

  • 将向客户端公开的逻辑 API 与各种微服务的物理实现分开。
  • 为所有客户端提供单一的入口点。客户端仅需要知道 API 网关的位置,而不是实现的每个微服务的位置。
  • 允许架构师基于使用 API 的客户端类型而提供特定于角色的 API。例如,API 网关可允许所有客户端读取资源,但将写入权限限制到具有合适的身份验证凭据的客户端。
  • 优化协调,减少请求数量。API 网关充当控制器,聚合从客户端请求的信息。对于移动客户端,这种聚合很重要,因为每个通过互联网来回传输的请求都会消耗大量时间和电池电量。这种协调还意味着,客户端仅需要发出一个请求。

在大多数情况下,这些益处多于必须实现和部署另一个服务的复杂性。这些好处也多于由于所有 API 都通过网关来路由而使网关成为通信瓶颈的潜在问题。

在我们的示例应用程序中,我们将使用 UI 作为 API 网关。UI 拥有呈现 Web 应用程序和充当应用程序的前端控制器(API 网关)的双重责任。

这非常适合小型的示例应用程序,但不应用在真实的产品应用程序中。人们常常希望为一个给定应用程序开发多个客户端。一个示例是 CLI 客户端、Web 客户端和移动客户端。无法通过将 API 网关与一个(单个)用户界面相耦合,轻松地实现更多客户端。

为微服务使用 CF Apps

在本教程中,cat 和 cart 微服务实现为 Cloud Foundry 应用程序。UI 客户端也实现为 Cloud Foundry 应用程序。所有基于微服务的应用程序的一个根本问题是,如何处理服务注册和服务发现。在这里,我们将使用 Cloud Foundry 清单文件来声明每个微服务和它的关联的 API 端点。

此方法具有易于实现的优势,不需要我们实现一个单独的服务注册表。它还允许应用程序源代码独立于它的封装。 您可将同样的 cat 源代码部署为 CF App 微服务,部署在基于 IBM Container 的微服务环境中。上下文使用环境变量传递,不需要访问服务注册表。

此方法的缺点是它是完全静态的;如果任何微服务端点有变动,您都需要执行一次全新的部署。

让我们在 Bluemix 上实现我们的购物应用程序。IBM Bluemix 等云平台提供了基本的高可用性、水平和垂直扩展功能。

第 1 步. 创建应用程序结构

  1. 为您的应用程序创建一个根目录 ("shop")。
  2. 为每个微服务("cat"、"cart")和 UI ("ui") 创建子目录。 为每个微服务和 UI 创建子目录
    为每个微服务和 UI 创建子目录
  3. 转到 Bluemix 并为 cat、cart 和 ui 创建应用程序。 为 cat、cart 和 ui 创建应用程序
    为 cat、cart 和 ui 创建应用程序

第 2 步. 创建清单文件

一个清单文件即可部署所有微服务(使用 cf push 命令)。该清单文件将 API 端点作为环境变量传递给每个微服务。

CF manifest.yml 文件控制微服务的部署,允许我们根据需要传递额外的环境变量。

清单 1. Hello Node.js
---
disk_quota: 1024M
domain: mybluemix.net
instances: 1
memory: 128M
env:
  MONGODB_URI: mongodb://<user>:<pass>@ds061112.mongolab.com:61112/IbmCloud_381vomtk_ppokkvq4
  CART_ENTRYPOINT: http://davet-cart.mybluemix.net
  CAT_ENTRYPOINT: http://davet-cat.mybluemix.net
applications:
- name: davet-cat
  path: ./cat/src/
- name: davet-cart
  path: ./cart/src
- name: davet-shop
  path: ./ui/src

该清单文件声明 3 个应用程序:davet-cat、davet-cart 和 davet-shop。用户界面是 davet-shop 应用程序,该清单文件还分别在环境变量 CAT_ENTRYPOINTCART_ENTRYPOINT 中声明了 cat 和 cart 的入口点 URL。

我们使用 MongoDB 数据库存储我们的产品信息。我们可以将 MongoLab 服务器连接到 CF 应用程序,但为简单起见,我们仅以环境变量形式传递 Mongo 连接字符串。

第 3 步. 添加部署文件

除了中央清单文件,每个微服务源代码目录还包含以下内容:

  • Procfile:指定在 CF 应用程序启动时要执行的命令
  • requirements.txt:Python 库需求
  • runtime.txt:CF 对要使用哪个 Python 运行时版本的声明

我们的示例中的每个 Cloud Foundry 应用程序都是在 Python 中使用 Flask 框架编写的。requirements.txt 文件指定可接受的 Flask 版本和需要的组件:

Flask == 0.10.0
pymongo >= 3.0

pymongo 是我们为 Python 使用的 MongoDB 数据库驱动程序。)

第 4 步. 实现微服务

本教程不会介绍如何将 cat、cart 和 ui 应用程序单独实现为简单的 Flask 应用程序。请参阅 源代码 了解详细信息。

清单文件声明了每个微服务的端点。Bluemix 将环境信息传递到清单中声明的所有 CF 应用程序,我们将依靠此信息来启动我们的应用程序。例如,UI 应用程序使用以下代码段来找到 cart 微服务:

CART_ENTRYPOINT = os.environ['CART_ENTRYPOINT'] if 'CART_ENTRYPOINT' in os.environ else ''

在一些 API 网关方法中,所有 流量都路由到 API 网关。这包括微服务之间的通信。在本例中,API 网关对内和对外都充当着应用程序的一个逆向代理。

在这里,我们选择了直接将 API 端点向所有微服务公开。这样做的优势是减少了微服务间的网络流量。

结束语

使用 CF App 清单文件来执行服务注册和发现,是创建基于微服务的应用程序的一种简单方法。不足之处在于服务注册的相对静态性。对一个新的清单文件执行 cf push 无法扩展到具有大量负载的云应用程序。另外,使用清单文件注册方法,无法支持红/黑部署和其他 DevOps 最佳实践。

您可使用 IBM Containers 修复这些问题。以服务注册和发现的更高复杂性为代价,可以支持自动扩展服务和动态修改服务,同时将宕机时间减到最少。

本系列的下一篇教程将演示如何使用 IBM Containers 实现微服务架构。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Cloud computing
ArticleID=1024247
ArticleTitle=在 Bluemix 中实现基于微服务的架构,第 1 部分:使用 CF Apps 执行构建和部署
publish-date=12152015