将单体式应用迁移到 Google Kubernetes Engine 上的微服务

Last reviewed 2022-12-29 UTC

本文向您介绍了在将单体式应用平台上的网站迁移到 Google Cloud 上重构之后基于容器的微服务平台的过程中涉及的主要概念。迁移按功能逐步进行,以避免大规模迁移事件及其相关风险。本文面向负责管理那些托管在单体式平台上且需要进行现代化改造的复杂网站的 IT 专业人员。阅读本文不需要具备 Google Cloud 或 Kubernetes 的深厚知识。

此类迁移的目标是为网站的各项功能提供一个更具灵活性和可扩缩性的环境,与单体式平台相比,在这样的环境下,功能更易于管理和更新。通过在此类环境中运行应用,您可以更快地改进各项已迁移的功能,同时为用户提供价值。

本文使用电子商务网站作为示例工作负载。许多电子商务网站使用专有的单体式平台构建而成,因此非常适合执行本文中描述的迁移。不过,本文描述的原理适用于很多类型的工作负载。只要您的系统和限制条件与本文的描述足够类似,您就可以从本文介绍的原理中获益。例如,用于预订酒店或租赁汽车的网站也非常适合此迁移模式。

迁移到 Google Cloud:使用入门一文所述,迁移到云端主要有三种模式:直接原样迁移、改进并迁移、淘汰并替换。本文介绍淘汰并替换模式的一种具体方案,采用该方案时,该模式逐步运用于应用的各项功能,而非运用于整个应用。

除了该迁移模式,本文还探讨了两种混合模式。在迁移过程中,应用采用混合架构,其中一些特性位于云端,一些特性仍在本地。迁移完成后,整个应用托管在云端,但仍与位于本地的后端服务进行交互。

术语

应用
在本文中,应用是完整的软件系统,可能具有许多功能,最终用户将应用视为一个单元。例如,电子商务网站是一个应用。可使用应用执行的所有操作均通过该应用的某个具体功能来完成。
功能
应用的功能单元。功能可以面向用户且作为应用的核心(如电子商务网站中的购物车),可以面向用户且为应用所要求(如登录),也可以属于应用内部(如电子商务网站的库存管理)。
服务
应用的独立组件。在本文中,应用由对最终用户不可见的不同服务组成。例如,网站使用的数据库就是一项服务。
单体式应用
作为单个可部署单元构建的应用。(也可简称为单体)。例如,单个 Java EE 应用或单个 .NET Web 应用。单体式应用通常与数据库和客户端用户界面相关联。
微服务
旨在容纳应用功能的单个服务。在微服务模式中,应用是多个服务的集合,每个服务具有一个特定目标。例如,您可能拥有一个为客户处理购物车的服务、一个处理付款的服务、一个与后端库存应用连接的服务。这些微服务应该松散耦合,且应通过明确定义的 API 相互连接。它们可以使用不同语言和框架进行编写,可以具有不同的生命周期。
混合架构
在该架构中,您将结合使用公有云服务商(如 Google Cloud)与在您自己的数据中心托管的私有资源。实现混合架构的原因和方式有多种,请参阅混合云和多云模式及做法一文,了解相关概述。
无状态服务和有状态服务
关于服务是否直接管理数据存储的指示。本文使用的无状态和有状态定义与十二要素应用方法相同。如果服务的运行不依赖任何数据,则服务无状态。 反之,则为有状态服务。例如,处理客户购物车的服务是有状态服务,因为购物车需要存储和检索。在后端系统中检查商品是否可供销售的服务是无状态服务 - 数据(状态)通过后端系统存储,而不是通过服务存储。

为什么要迁移到微服务?

将应用分解为微服务具有以下优势,而大部分优势基于微服务是松散耦合的这一性质。

  • 微服务可以独立测试和部署。部署单元越小,部署就越简单。
  • 它们能够以不同的语言和框架实现。对于每个微服务,您可以随意选择最适合特定用例的技术。
  • 它们可以由不同团队管理。微服务之间的边界可让您更轻松地为一个或多个微服务专门安排一个团队。
  • 通过迁移到微服务,您可以解除团队之间的依赖。每个团队只需关注其所依赖的微服务的 API 即可。团队无需考虑如何实现这些微服务,以及这些微服务的发布周期等。
  • 您可以更轻松地设计故障预防机制。通过在服务之间划分明确边界,您可以更轻松地确定当服务出现故障时,该做什么。

与单体式应用相比,微服务具有以下缺点:

  • 由于基于微服务的应用是不同服务组成的网络,而且这些服务通常以不明显的方式进行交互,因此系统的整体复杂性往往会增加。
  • 与单体式应用的内部不同,微服务通过网络进行通信。在某些情况下,这可能会被视为安全问题。 Istio 通过自动加密微服务之间的流量来解决此问题。
  • 由于服务之间存在延迟,可能难以达到与单体式应用方法相同水平的性能。
  • 系统的行为不是由单个服务引起的,而是由许多服务及服务交互引起的。因此,了解您的系统在生产环境中的行为方式(其可观测性)变得更加困难。 Istio 也可以解决这一问题。

虽然 Google 这样的一些公司多年来一直使用微服务,但相关概念(及其与面向服务的架构 (SOA) 的关系)是由 James Lewis、Martin Fowler 和 Sam Newman 在他们的微服务文章中正式提出的。

迁移过程概览

本文中描述的迁移过程漫长,可能需要数月时间才能完成,因为这是一个大规模项目。本部分内容描绘了从本地单体式应用转为完全托管在 Google Cloud 上且使用微服务构建的应用的路径。

起点:本地单体式应用

本文假设您目前正在本地运行单体式应用。下面的概要架构图可能与您当前的架构类似。

典型单体式应用的架构

该图并不能完全代表您当前的系统。 在类似这样的架构中,通常包含的一些技术有:

  • 关系型数据库,如 Oracle® 数据库或 SAP HANA
  • 电子商务平台,如 Oracle ATG 或 SAP Hybris
  • Apache Solr 或其他搜索引擎

终点:Google Cloud 上的基于微服务的应用

此处描述的迁移过程是指从本地单体式架构迁移到 Google Cloud 上运行的基于微服务的架构。目标架构如下所示:

迁移到容器和 GKE 后的架构

在目标架构中,您在 Google Kubernetes Engine (GKE) 中运行微服务。 Kubernetes 是一个用于管理、托管、扩缩和部署容器的平台。容器是一种可移植的代码封装和运行方式。它们非常适合微服务模式,使用容器时,每个微服务可以在各自的容器中运行。 微服务可以通过由 Cloud InterconnectCloud VPN 创建的私有网络连接来调用后端系统。或者,您可以使用 Apigee 公开您的后端服务并保护对后端服务的访问。如需详细了解这些产品并在它们之间进行选择,请参阅本文档后文 Apigee、Cloud VPN 和 Cloud Interconnect 中的内容。

微服务也可以与许多其他 Google Cloud 产品进行交互,具体取决于其需求。Cloud StorageCloud SQL 是适用于电子商务应用的两种最常用的 Google Cloud 产品。Pub/Sub 可用作适用于异步工作的不同微服务之间的消息总线。

您可以通过两种方式在互联网上公开您的应用:对于映像等资源,直接使用 Google Cloud 负载平衡器,对于公共 API,可以选择使用 Apigee

下表列出了您可以在目标架构中使用的产品。这些产品并非全部必须使用,是否使用它们取决于具体用例。

网络

Google Cloud 产品 用途 备注
Virtual Private Cloud VPC 是软件定义的专用网络,您的资源(如 GKE 集群)位于该网络中。VPC 包括防火墙和路由等特性。VPC 可在全球范围内使用,允许在全球建立基于 Google 拥有的光纤网络的专用连接。 在该架构中,Cloud VPC 是必需的。
Cloud Interconnect Cloud Interconnect 通过可用性高、延迟时间低的连接将您的本地网络扩展至 Google 的网络。您可以使用专用互连直接连接到 Google,也可以使用合作伙伴互连通过受支持的服务提供商连接到 Google。 您的电子商务网站可能需要调用本地的后端服务,如仓库管理系统或结算系统。
Cloud Interconnect 是其中一个解决方案。
Cloud VPN Cloud VPN 通过 IPsec VPN 隧道将您的本地网络安全地扩展至 Google 的网络。流量经过加密,通过公共互联网在两个网络之间传输。Cloud VPN 对于数据量较少的连接非常有用。 您的电子商务网站可能需要调用本地的后端服务,如仓库管理系统或结算系统。
Cloud VPN 是其中一个解决方案。
Cloud Load Balancing Cloud Load Balancing 是 Google 的托管式负载平衡解决方案。它支持 L4 (TCP/UDP) 和 L7 (HTTP) 负载平衡,还可用作 SSL (HTTPS) 终止端点。创建 Google Cloud 负载平衡器可为您提供单个 Anycast IP。得益于 Google 的优质层级网络,尝试访问此 IP 的所有用户将自动路由到最近的 Google 接入点,以缩短网络延迟时间。 在该架构中,Cloud Load Balancing 是必需的。
Cloud CDN Cloud CDN(内容分发网络)可利用 Google 的全球分布式边缘接入点,在您用户的邻近位置缓存经过 HTTP(S) 负载平衡处理的内容。通过在 Google 的网络边缘缓存内容,您可以在降低传送费用的同时,更快地为用户分发内容。 在此场景中,Cloud CDN 不是必需的,但建议采用,尤其是对于静态内容。

平台

Google Cloud 产品 用途 备注
Google Kubernetes Engine (GKE) GKE 是 Google 的托管式 Kubernetes 产品,用于部署容器化应用。GKE 完全符合开源 Kubernetes 的规范,并提供许多高级功能,如区域级集群(实现高可用性)、专用集群垂直 Pod 自动扩缩集群自动扩缩GPU抢占式节点 在该架构中,GKE 是必需的。
Istio Istio 采用统一的方式来保护、连接和监控微服务,降低了管理微服务部署的复杂性。 在该架构中,Istio 不是必需的,但其提供有用的特性,如增强监控、流量加密和路由,以及故障注入,用于测试您应用的弹性。
Apigee Apigee 是托管式 API 网关。通过使用 Apigee,您可以安全地设计、发布、监控您的 API 并通过 API 获利。
您可以使用 Apigee 公开公共 API 和私有 API。在微服务架构中,公共 API 托管在 Google Cloud 上,而后端本地系统可以作为仅供 Google Cloud 上的微服务使用的私有 API 公开。
在该架构中,Apigee 不是必需的,但建议通过公共 API 来传送您网站的所有内容。Apigee 等 API 网关提供许多 API 管理功能,如配额、版本控制和身份验证。
Pub/Sub Pub/Sub 是消息传递和流式传输系统。如果在该架构中使用,它将用作微服务之间的消息总线,从而实现微服务之间的异步工作流。 Pub/Sub 不是必需的,但发布者/订阅者模式可帮助缓解扩缩问题。

存储

Google Cloud 产品 用途 备注
Cloud Storage Cloud Storage 提供统一的对象存储 API,适合许多用例,如传送网站内容、备份和归档数据、分发大对象。对于电子商务网站,Cloud Storage 的主要用途是存储和传送静态资源,如产品图片和视频。 Cloud Storage 的无缝可扩缩性,再加上 Cloud CDN,使其非常适合本文档中描述的微服务架构。因此,建议使用。
Firestore Firestore 是一种快速的全托管式 NoSQL 文档数据库。 在该架构中,Firestore 不是必需的,但非常适合电子商务网站中的多个常见用例。例如,您可以用其存储用户购物车和用户元数据。
Cloud SQL Cloud SQL 是适用于 MySQL 和 PostgreSQL 的 Google 托管式产品。这些关系型数据库的用途广泛。 在此场景中,Cloud SQL 不是必需的,但非常适合电子商务网站中的多个常见用例。例如,您可以使用 Cloud SQL 来存储订单,允许轻松汇总和计算。
Cloud Spanner Spanner 是一种具备横向扩容能力和强一致性的全球关系型数据库。凭借可实现 99.999% 的正常运行时间的服务等级协议 (SLA)(针对多区域实例),它可确保业务关键型数据的极高可用性。 在此场景中,Spanner 不是必需的。由于 Spanner 是一种关系型数据库,可在全球范围内实现事务一致性,因此非常适合那些面向国际用户群的电子商务网站。
Memorystore Memorystore for Redis 是托管版的 Redis 服务,后者是一种内存中键值对数据库。作为延迟时间较低的数据库,Redis 非常适合处理经常访问的数据。 在此场景中,Memorystore 不是必需的,但非常适合网站常见的多个用例,如存储用户会话信息和提供应用缓存。

您也可以使用其他 Google Cloud 产品,该列表列出的是电子商务架构中最常见的产品。您还应该考虑到,随着该架构的自然演变,将需要增加组件,以便利用 Cloud BigtableBigQueryVertex AI 等产品从数据中收集资讯。

此外,如果您目前所用的部分技术仍能满足您的需求,或者其迁移费用过高,您也可以继续在该目标架构中使用这些技术。以下示例说明了如何在 Google Cloud 上运行常见电子商务技术:

  • Google Cloud 合作伙伴可以管理您的 Oracle 工作负载,使这些工作负载与您的 Google Cloud 基础架构之间的延迟时间保持在亚毫秒级。如此,您还可以重复使用现有许可。
  • 得益于 SAP 和 Google Cloud 之间的合作伙伴关系,您可以在 Google Cloud 上运行各种 SAP 工作负载,包括 HANAHybris
  • 您可以在 GKE 上运行 Apache Solr,或者使用 Google Cloud Marketplace 上提供的一些 Solr 解决方案。
  • 您可以在 GKE 上运行 Elasticsearch(例如,通过使用 Cloud Marketplace 解决方案),或通过在 Google Cloud 上构建的 Elastic 来使用代管式服务

Apigee、Cloud VPN 和 Cloud Interconnect

在该项目早期您必须做出的其中一个最重要的决策是,如何处理在 GKE 上托管的新微服务和您的本地旧版系统之间的通信。有两个可以共存的主要解决方案:基于 API 的通信或基于专用连接的通信。

在基于 API 的解决方案中,您使用 API 管理解决方案(如 Apigee)作为两个环境之间的代理。采用这种方式,您可以精确控制要公开旧版系统的哪些部分,以及如何公开。您还可以无缝重构 API 的实现(也就是说,从旧版服务转为微服务),而不影响 API 的使用者。下图显示了 Apigee、您的本地系统和您的 Google Cloud 系统之间的交互。

Apigee 作为代理,位于本地系统和 Google Cloud 系统组合的前端

借助 Apigee 大规模部署 Kubernetes API 的模式和 Apigee 电子书《借助 API 超越 ESB 架构》(Beyond ESB Architecture with APIs) 可以帮助您了解该设计。

在基于专用连接的解决方案中,您使用专用网络连接来连接您的 Google Cloud 和本地环境。微服务通过该连接与您的旧版系统进行通信。您可以通过 Cloud VPN 设置基于 IPSec 的 VPN 隧道。Cloud Interconnect 提供可用性高、延迟时间低的连接,以满足较大的带宽需求。如需简要了解不同选项,请参阅选择互连类型

下图显示了您的本地系统和 Google Cloud 系统之间通过 Cloud VPN 或 Cloud Interconnect 的交互。

Cloud Interconnect 或 Cloud VPN 连接本地系统和基于 Google Cloud 的系统

基于 API 的解决方案由应用团队实现。与基于专用连接的解决方案相比,在项目之初,该解决方案需要与旧版应用进行更大程度地集成。但从长远来看,基于 API 的解决方案提供更多管理选项。基于 Cloud VPN 或 Cloud Interconnect 的解决方案将由网络团队实现,最初所需的与旧版应用的集成较少。但从长远来看,该解决方案没有任何附加价值。

迁移过程

本部分概述了迁移到新架构时需要遵循的简要步骤。

前提条件

在将第一个微服务迁移到 GKE 之前,您需要准备好要在其中执行操作的 Google Cloud 环境。在 GKE 上将第一个微服务投入生产环境之前,请解决以下问题:

  • 设置您的 Google Cloud 组织,这是将用于托管您的 Google Cloud 资源的全局环境。执行此步骤的过程中,您还需要配置您的 Google 身份(即相应账号)。您所在组织的员工需要这些账号才能使用 Google 产品。如需了解详情,请参阅确定如何将身份添加到 Google Cloud
  • 设计 Google Cloud 政策以便控制您的 Google Cloud 资源。面向企业客户的政策设计一文将为您提供帮助。
  • 制定计划以使用基础架构即代码 (IaC) 部署您的 Google Cloud 资源,包括 GKE 集群。您将获得可重现且可审计的标准化环境。 建议使用 Cloud Deployment ManagerTerraform 来达成此目的。
  • 研究不同的 GKE 功能,并根据需要进行调整。对于业务关键型应用,您可能需要更改一些默认设置,并强化您的集群。 强化集群的安全性包含有关如何实现这一目标的信息。
  • 为 Kubernetes 构建您的持续集成/持续交付 (CI/CD) 工具。您可以使用 Cloud Build 构建容器映像,使用 Container Registry 存储映像并检测漏洞。您还可以将这些产品与您的现有 CI/CD 工具结合使用。利用该工作来实现构建操作容器的最佳做法。在项目早期执行此操作可避免生产阶段出现问题。
  • 根据您选择的选项,设置 Apigee 账号,或通过 Cloud VPN 或 Cloud Interconnect 在 Google Cloud 和您的本地数据中心之间建立专用连接。

分阶段迁移

您应该将电子商务网站的特性逐个迁移到新环境,在必要时创建微服务。这些微服务可以根据需要回调到旧版系统。

该方法相当于将迁移的主要部分进行了转变,并且将整体项目重构为多个较小的项目。使用该方法有两大优势:

  • 与整个迁移项目相比,每个较小的项目更容易界定,且更易于推断。一次迁移整个网站要求团队对系统、限制条件、依赖于该网站的正常运行的第三方系统等各方面之间的交互有更深入的了解。这增加了出错的风险。
  • 重构为多个较小的项目可为您提供灵活性。如果您有一个规模较小的团队,则该团队可以逐一处理这些项目,不会变得不堪重负。如果您有多个团队,您或许可以并行执行一些工作,并同时主导多个迁移。

选择要迁移的特性和迁移时间是您要在项目的这个阶段制定的最重要决策之一。制定该决策时,您必须考虑特性之间的依赖项网络。一些特性可能严重依赖于其他特性才能正常工作,而其他特性可能相当独立。特性具有的依赖项越少,就越容易迁移。下文中的您应该先迁移哪些特性?部分详细介绍了依赖项问题,以及在决定要迁移的特性时需要考虑的其他因素。

示例:迁移购物车

为了说明迁移过程,本部分演示了单个特性(即电子商务网站的购物车)的迁移。

要了解该特性的依赖项,请考虑典型的用户操作历程,以及在单体式应用中实现该特性的方式:

  1. 用户在浏览网站,寻找他们感兴趣的商品。
  2. 用户点击添加到我的购物车。此操作会触发从用户浏览器到购物车特性的 API 调用。这是第一个依赖项:前端对购物车执行操作。
  3. 购物车特性收到调用后,会检查该商品是否有货。此事件触发从购物车特性到库存处理系统的 API 调用。这是第二个依赖项:购物车依赖于库存子系统。
  4. 如果商品有货,则购物车功能会存储“用户 A 的购物车里有 1 个商品 X 的实例”这样的信息。这是第三个依赖项:购物车需要一个数据库来存储该信息。
  5. 当用户结算并进行到付款流程时,付款子系统会查询购物车以计算总额。 付款完成后,付款子系统会通知购物车功能清空购物车。这是第四个依赖项:付款子系统查询购物车。

总而言之,前端和付款子系统会调用购物车特性,购物车特性会查询数据库和库存子系统。

文档数据库非常适合用于存储购物车。对于购物车数据,关系型数据库显得大材小用,购物车可以按用户 ID 轻松编入索引。 Firestore 是一个托管式无服务器 NoSQL 文档数据库,非常适合该用例,因此建议使用它作为目标架构的数据存储系统。

您可以通过多种方式迁移购物车数据。(相关内容在稍后的数据迁移策略部分详细介绍。) 本文档假定后文中描述的计划性维护方法可接受。如果满足这些条件,您可以按照以下简要步骤来迁移购物车功能:

  1. 创建一个用于实现购物车 API 的新微服务。使用 Firestore 存储购物车。确保该新的微服务可以调用库存子系统。
  2. 创建一个脚本,从旧版购物车子系统中提取购物车,并将其写入 Firestore。将脚本编写为可让您能够根据需要多次重新运行,并且仅复制自上次执行以来发生更改的购物车。
  3. 创建一个以相反方式执行相同操作的脚本:将购物车从 Firestore 复制到旧版系统。仅在您需要回滚迁移时才应使用该脚本。
  4. 通过 Apigee 公开购物车 API。
  5. 准备并测试对前端和付款子系统的修改,使它们能够调用您的新购物车微服务。
  6. 运行您在第 2 步中创建的数据迁移脚本。
  7. 将您的网站置于维护模式。
  8. 重新运行数据迁移脚本。
  9. 将第 5 步中的修改部署到旧版生产系统。
  10. 在您的网站中停用维护模式。

现在,网站的购物车功能已成为托管在 Google Cloud 上的微服务。第 5 步可能是该过程中最困难的步骤,因为需要您修改旧版系统。不过,随着您将更多功能迁移到微服务,该步骤会变得简单,因为越来越多的依赖项已经变成微服务。因此,与在单体式应用中相比,它们的耦合更加松散,更易于修改和部署。

另一种迁移方式是让新的微服务回调到原始购物车数据库,然后将数据迁移到 Firestore。要在这两个迁移模型之间选择,请考虑微服务和原始数据库之间的延迟时间、架构重构的复杂性、您想要采用的数据迁移策略。

您应该先迁移哪些特性?

本部分帮助您确定首先要迁移的特性 - 初始迁移工作。为了降低复杂迁移的固有风险,分治法始终是首选。

规划迁移时,人们很容易从易于迁移的特性开始。这种做法或许能够快速见效,但对于您的团队而言,可能不是最佳学习经历。您应该花时间评估所有特性,并为迁移制定计划,而不是直接进行迁移。

您可以使用下面的评估领域列表作为逐个特性分析的框架:

  • 业务流程
  • 设计和开发
  • 运营
  • 人员和团队

业务流程评估

在初始迁移过程中,迁移团队将学习和开发流程,他们可能会犯错。因此,这些初始工作不应该涉及业务关键型系统(以避免影响主要业务线),而是应该代表重要的用例(为团队提供学习的机会)。评估业务流程时,除了开发流程,还需考虑与合规性及许可相关的流程。

设计和开发评估

从设计和开发的角度来看,理想的初始迁移工作是指对其他特性和数据依赖最少的工作,并且最容易重构(如有必要)。

您应该分析每个特性,考虑其依赖项和重构所需的工作。如要对每个特性执行依赖项分析,请注意以下方面:

  • 依赖项的类型 - 来自数据或其他特性的依赖。
  • 依赖项的规模 - 该特性的依赖项变化可能会影响多少个特性。

出于以下原因,迁移严重依赖数据的特性通常是一项复杂的任务:

  • 如果您决定先迁移特性,稍后再迁移相关数据,您必须考虑到在初始迁移工作完成后,生产者、使用者和数据存储区之间的网络延迟时间有所增加。
  • 在迁移阶段,将出现数据完整性和同步挑战,因为您可能会临时从多个位置读取以及向其中写入数据。

另外需要评估每项功能所需的重构量。 潜在重构取决于功能的当前设计及其未来方向。您需要考虑该工作可能会对相关业务流程产生什么影响。

下面是您在该评估期间需要回答的最重要的问题:

  • 该特性使用哪些数据?
  • 该功能使用的数据量是多少?
  • 该功能是否需要其他功能才能正常工作?
  • 该功能的变化会影响多少个其他功能?
  • 该功能是否有任何网络或连接要求?
  • 该功能的当前设计如何影响重构?

运营评估

从运营的角度来看,您还应该考虑哪些特性可以承受切换期停机时间。如果您需要最大限度缩短停机时间,迁移要求高可用性的特性可能意味着需要额外的操作。

人员和团队评估

最好选择已制定明确流程的团队来主导初始迁移工作。此外,团队应该愿意为迁移之旅铺平道路,了解他们将会遇到新的挑战,并且必须找到合适的解决方案。

选择初始迁移工作

根据该评估框架,理想的初始迁移工作应该具有足够大的挑战性,这样才有意义,但也应该足够简单,以最大限度降低失败的风险。初始迁移过程还应该具备以下特点:

  • 考虑到特性本身及相关业务流程,需要进行少量重构。
  • 无状态,即没有外部数据要求。
  • 依赖项很少或者没有。

迁移计划示例

下面的列表显示了迁移顺序的示例:

  1. 平台前端;即界面
  2. 无状态特性,例如货币转换服务
  3. 带有独立数据集的特性(对其他数据集没有依赖的数据集),例如用于列出实体店的服务
  4. 带有共享数据集的特性 - 电子商务平台的业务逻辑

平台前端和无状态特性

平台前端和无状态特性通常具有少量依赖项。它们都是理想的初始迁移候选对象,因为它们是架构的重要组件。它们所需的重构有限,因为在初始迁移阶段,后端 API 仍通过旧版数据中心提供,或者通过由其他云服务商托管的运行时环境提供。

对于平台前端特性和无状态特性,请专注于集成和部署流水线。由于您的 GKE 工作负载必须实现容器化,因此您可能必须执行更多运营工作。

带有独立数据集的特性

接下来要迁移的组件是数据集独立于其他数据集的特性。与具有依赖项的数据集相比,这些独立数据集更容易从您的旧版系统中提取。(当然,与迁移无状态功能相比,迁移带有独立数据集的功能需要额外的工作,即在实际迁移数据的同时,创建和管理新的数据存储区。)

规划数据迁移时,您可以选择存储系统。 由于您想要对您的应用进行现代化改造,因此可以使用以下服务:

  • 托管式数据存储服务,如 Cloud Storage 或 Filestore,用于存储文件
  • Cloud SQL,用于从 RDBMS 迁移数据
  • Firestore,用于从 NoSQL 数据库迁移数据

带有共享数据集的功能

带有共享数据集的特性最难迁移。这是因为由于对一致性、分发、访问和延迟时间的要求,迁移数据是一项极富挑战性的任务,如下文所述。

数据迁移策略

如需详细了解数据迁移方法,请参阅数据迁移方法

微服务最佳做法

以下部分包括在设计、编写和部署微服务时应遵循的一组最佳做法。

设计微服务

设计微服务时,请遵循适当的设计模式,以便正确判断每个微服务的上下文和边界。这样可以保护您,避免微服务工作负载发生不必要的碎片化。您还可以定义微服务在其中有效的精确上下文(或域)。例如,域驱动型设计 (DDD) 就是这样一种设计模式。

API 合约

每个微服务应该仅通过一组接口来调用。反过来,每个接口应该由可使用 OpenAPI 计划规范(前身为 Swagger)或 RAML 等 API 定义语言实现的合约明确定义。拥有明确定义的 API 合约和接口后,您可以根据这些 API 接口开发测试,并将测试作为您解决方案的主要组成部分(例如,通过应用测试驱动开发)。

管理更改

如果您必须在 API 合约中引入破坏性更改,则应该提前做好准备,以最大限度减少客户端应对更改所需的重构工作。要处理该问题,有两种方法:

  • 版本控制
  • 实现新的微服务

版本控制

为了灵活地管理可能会破坏现有客户端的更新,您应该为您的微服务实现版本控制方案。通过版本控制,您可以部署微服务的更新版本,而不影响正在使用现有版本的客户端。如果使用版本控制,则每次引入会破坏现有合约任意部分的更改(即使更改微乎其微)时,您都必须创建新版本。

您可以使用以下方案来实现版本控制方案:

  • 全局版本控制
  • 资源版本控制

实现全局版本控制方案时,这意味着您将对整个 API 进行版本控制。一种实现是将版本信息构建到资源 URI 中,比如:

/api/v1/entities or api.v3.domain.tld/entities

这种版本控制方案易于部署,因为版本控制在一个位置进行管理。但该方案的灵活性不如资源版本控制方案。如需查看全局版本控制方案的示例,请参阅 Kubernetes API 版本控制方案

通过资源版本控制方案,您可以对微服务提供的每个资源进行独立版本化。为实现最大灵活性,您甚至可以根据对给定资源(例如,HTTP 谓词)执行的操作来对该资源进行版本化。您可以通过各种方式实现此版本控制方案。您可以使用 URI,也可以使用自定义或标准 HTTP 请求标头,如以下示例所示:

Accept: application/tld.domain.entities.v2+json

资源版本控制方案可能比全局版本控制方案更难设计,因为您需要为所有实体采用一个通用方法。但是,该方案更加灵活,因为您可以为资源实现不同且独立的升级政策。

实现新的微服务

处理破坏性更改的另一个方法是实现带有新合约的全新微服务。如果新版微服务需要的更改较多,以至于编写新版本比更新现有版本更加合理,那么您可能需要实现新的微服务。虽然该方法提供最大灵活性,但也可能为微服务提供重叠的功能与合约。实现新的微服务后,您可以逐步重构客户端,以使用该新的微服务并从旧版微服务迁移。

后续步骤