微服务简介

Last reviewed 2021-06-24 UTC

本参考指南是由四个部分组成的系列教程中的第一篇,该系列教程介绍了如何设计、构建和部署微服务。本系列文章介绍微服务架构的各种元素。该系列介绍了微服务架构模式的优缺点及其应用方式。

  1. 微服务简介(本文档)
  2. 将单体式应用重构为微服务
  3. 微服务设置中的服务间通信
  4. 微服务应用中的分布式跟踪

本系列文章面向设计和实施迁移以将单体式应用重构为微服务应用的应用开发者和架构师。

单体式应用

单体式应用是一个单层软件应用,其中不同的模块会组合成一个程序。例如,如果您正在构建电子商务应用,该应用将具有与面向对象的编程 (OOP) 原则一致的模块化架构。下图显示了一个电子商务应用设置示例,其中的应用包含各种模块。在单体式应用中,模块结合使用编程语言结构(如 Java 软件包)和构建工件(如 Java JAR 文件)。

单体式应用使用多个模块。

图 1. 单体电子商务应用示意图,其中融合了编程语言结构。

在图 1 中,电子商务应用中的不同模块分别对应于付款、送货和订单管理方面的业务逻辑。所有这些模块均被打包并部署为一个逻辑可执行文件。实际格式取决于应用的语言和框架。例如,许多 Java 应用都打包为 JAR 文件,并部署在 Tomcat 或 Jetty 等应用服务器上。同样,Rails 或 Node.js 应用被打包为目录层次结构。

单体式应用的优势

单体式架构是一种用于构建应用的传统解决方案。以下是为应用采用单体式设计的一些优势:

  • 您可以使用 Selenium 等工具对单体式应用进行端到端测试。
  • 要部署单体式应用,您只需将封装的应用复制到服务器。
  • 单体式应用中的所有模块都共用内存、空间和资源,因此您可以使用一种解决方案来解决交叉问题,例如日志记录、缓存和安全。
  • 单体式方法可提供性能优势,因为模块可以直接调用。相比之下,微服务通常需要网络调用才能相互通信。

单体式挑战

复杂的单体式应用通常越来越难以构建、调试和推理。有时,这种问题大于收益。

  • 应用通常会随着时间的推移而增长。在具有紧密耦合的模块的大型复杂应用中实现更改可能变得非常复杂。由于代码更改会影响整个系统,因此您必须要协调好所有更改。与微服务应用相比,协调更改使整体开发和测试过程花费的时间更长。
  • 使用单体式应用实现持续集成和部署 (CI/CD) 可能很复杂。这种复杂性是因为您必须重新部署整个应用才能更新其任何一个部分。此外,您可能还必须对整个应用进行大量手动测试以检查是否出现回归问题。
  • 当不同模块的资源要求存在冲突时,单体式应用可能难以扩缩。例如,一个模块可以实现 CPU 密集型图像处理逻辑。另一个模块可能是内存数据库。由于这些模块部署在一起,因此您必须在硬件选择上做出妥协。
  • 由于所有模块都在同一进程内运行,因此任何模块(如内存泄漏)中的错误都可能导致整个系统崩溃。
  • 当您想要采用新的框架和语言时,单体式应用会增加复杂性。例如,重写整个应用以使用新框架的成本很高(在时间和金钱方面),即使该框架明显更好。

基于微服务的应用

微服务通常实现一组不同的特性或功能。每个微服务都是一个具有专属架构和业务逻辑的迷你应用。例如,某些微服务会公开由其他微服务或应用的客户端使用的 API,例如与付款网关和物流的第三方集成。

图 1 展示了包含多个模块的单体式电子商务应用。下图展示了可能将电子商务应用分解为微服务:

单体式应用被分解为微服务。

图 2. 包含由微服务实现的职能领域的电子商务应用的示意图。

在图 2 中,专用微服务实现了电子商务应用的每个功能区域。每个后端服务都可能会公开一个 API,而服务则会使用其他服务提供的 API。例如,要呈现网页,界面服务会调用结账服务和其他服务。服务还可以使用基于消息的异步通信。如需详细了解服务之间的通信方式,请参阅本系列中的第三个文档:微服务设置中的服务间通信

微服务架构模式会显著改变应用和数据库之间的关系。我们建议每个服务都有最适合自己要求的数据库,而不是与其他服务共享单个数据库。每项服务都有一个数据库时,请确保服务之间的松散耦合,因为所有数据请求都通过服务 API 进行,而不是直接通过共享数据库。下图显示了微服务架构模式,其中每个服务都有自己的数据库:

每个微服务都有自己的数据库。

图 3.微服务架构中的每项服务都有自己的数据库。

在图 3 中,电子商务应用中的订单服务使用具有实时搜索功能的面向文档的数据库很好地运行。付款和传送服务依赖于关系型数据库的强原子性、一致性、隔离性、持久性 (ACID) 保证。

微服务优势

微服务架构模式解决了前面的单体式挑战部分中所述的复杂性问题。微服务架构具有以下优势:

  • 虽然总功能保持不变,但您可以使用微服务将应用程序分成可管理的区块或服务。每个服务都采用 RPC 或消息驱动型 API 的形式进行明确定义的边界。因此,单个服务可以更快地开发,更易于理解和维护
  • 自主团队可以独立开发独立的服务。您可以围绕业务边界(而不是产品的技术功能)来组织微服务。您可为您的团队安排一个独立的责任,让其负责所分配软件的整个生命周期(从开发、测试、部署到维护和监控)。
  • 独立的微服务开发流程还可让您的开发者使用不同编程语言编写每个微服务,从而创建 Polyglot 应用。为每个微服务使用最有效的语言时,您可以更快地开发应用,并优化应用以降低代码复杂度并提高性能和功能。
  • 将功能与单体式应用分离后,您可以让独立团队独立发布其微服务。独立的发布周期可以帮助您的团队提高产品速度并缩短产品上市时间。
  • 微服务架构还可让您独立扩缩每个服务。您可以部署满足其容量和可用性限制条件的每项服务的实例数。您还可以使用与服务的资源要求最相符的硬件。独立扩缩服务有助于提高整个系统的可用性和可靠性。

以下是从单体式应用迁移到微服务架构的一些具体实例:

  • 实现扩缩能力、可管理性、敏捷性或交付速度的改进。
  • 逐步将大型旧式应用重写为现代语言和技术栈,以满足新的业务需求。
  • 提取跨行业业务应用或跨行业服务,以便跨多个渠道重复使用这些应用。您可能希望重复使用的服务示例包括付款服务、登录服务、加密服务、航班搜索服务、客户个人资料服务和通知服务。
  • 采用专用语言或框架来实现现有单体式应用的特定功能。

微服务挑战

与单体式应用相比,微服务有一些挑战,其中包括:

  • 微服务的一个主要挑战是由于应用是一个分布式系统而引起的复杂性。开发者需要选择和实现服务间通信机制。并且还必须处理上游服务的部分故障和不可用。
  • 微服务的另一个挑战是您需要跨不同微服务(也称为分布式事务)管理事务。更新多个业务实体的业务操作相当常见,它们通常以原子方式应用,应用所有操作或所有操作都失败。将多个操作封装在单个数据库事务中时,可以确保原子性。

    在基于微服务的应用中,业务操作可能分布在不同的微服务中,因此您需要更新不同服务拥有的多个数据库。如果发生故障,跟踪不同的微服务调用或成功调用是否成功非常重要。如果因回滚失败而未正确执行状态回滚,则最糟糕的情况可能会导致服务之间出现数据不一致的问题。如需了解在服务之间设置分布式事务的各种方法,请参阅本系列的第三篇,微服务设置中的服务间通信

  • 对基于微服务的应用进行全面测试比测试单体式应用更复杂。例如,要测试在单体式电子商务服务中处理订单的功能,请选择商品,将其添加到购物车,然后签出。为了在基于微服务的架构中测试相同的流,多项服务(例如前端、订单和付款)会相互调用,以完成测试运行。

  • 部署基于微服务的应用比部署单体式应用更复杂。微服务应用通常由许多服务组成,每个服务都具有多个运行时实例。您还需要实现一项服务发现机制,使服务能够发现需要与之通信的任何其他服务的位置。

  • 微服务架构会增加操作开销,因为要监控和提醒的服务更多。由于服务间通信的增加,微服务架构也有更多故障点。单体式应用可能会部署到小型应用服务器集群。基于微服务的应用可能有数十种单独的服务来构建、测试、部署和运行,并且可能支持多种语言和环境。所有这些服务都需要进行聚簇以实现故障切换和弹性。生产环境中的微服务应用需要高质量的监控和运营基础架构。

  • 微服务架构中的服务划分可让应用同时执行更多功能。不过,由于模块作为独立服务运行,因此由于服务之间的网络调用,响应会引入延迟时间。

  • 并非所有应用都足够大,可以细分为微服务。此外,某些应用要求组件之间紧密集成,例如必须处理快速实时数据流的应用。服务之间的任何额外通信层可能会减慢实时处理的速度。提前考虑服务之间的通信可以清楚地标记服务边界。

在确定微服务架构是否最适合您的应用时,请考虑以下几点:

  • 微服务最佳做法需要每项服务数据库。为应用进行数据建模时,请注意每项服务数据库是否适合您的应用。
  • 实现微服务架构时,您必须检测和监控环境,以便找出瓶颈、检测和防止故障,以及支持诊断。
  • 在微服务架构中,每项服务都有单独的访问权限控制。为帮助确保安全性,您需要保护对环境内以及使用 API 的外部应用的每项服务的访问权限。
  • 同步服务间通信通常会降低应用的可用性。例如,如果电子商务应用中的订单服务在上游同步调用其他服务,如果这些服务不可用,则无法创建订单。因此,我们建议您实现异步、基于消息的通信。

何时将单体式应用迁移到微服务

如果您已成功运行单体式应用,则采用微服务对您的团队而言是一项重大投资成本。不同的团队采用不同的方式来实现微服务的原则。对于微服务的规模或所需微服务数量,每个工程团队都有独特的结果。

如需确定微服务是否是应用的最佳方法,请首先确定要解决的关键业务目标或痛点。实现目标或解决您发现的问题可能更简单。例如,如果您希望加快应用扩容速度,您可能会发现自动扩缩是一种更高效的解决方案。如果您在生产环境中发现错误,则可以首先实现单元测试和持续集成 (CI)。

如果您相信微服务方法是实现目标的最佳方法,请首先从单体式应用中提取一项服务,然后对其进行开发、测试和部署。如需了解详情,请参阅本系列中的下一个文档:将单体式应用重构为微服务。成功提取一项服务并将其在生产环境中运行后,请开始提取下一项服务,并从每个周期继续学习。

微服务架构模式将系统分解为一组可独立部署的服务。开发单体式应用时,您必须协调大型团队,这可能导致软件开发缓慢。在实现微服务架构时,您可以让小型自主团队并行工作,从而加快开发速度。

在本系列的下一篇(将单体式应用重构为微服务)中,您将了解将单体式应用重构为微服务的各种策略。

后续步骤