微服务不只是编写代码(微服务模式)

1.9 微服务不只是编写代码

尽管构建单个微服务的概念很容易理解,但运行和支持健壮的微服务应用程序(尤其在云中运行)不只是涉及为服务编写代码。

编写健壮的服务需要考虑几个主题

微服务不只是编写代码(微服务模式)

图 1-7 提及的要点

  • 大小适当 —— 确保正确地划分微服务大小,以避免微服务承担太多的职责
  • 位置透明 —— 多个服务实例可以快速启动和关闭时,管理服务调用的物理细节。
  • 有弹性 —— 绕过失败的服务,确保采取“快速失败”的方法来保护微服务消费者和应用程序的整体完整性。
  • 可重复 —— 确保提供的每个新服务实例与生产环境中的所有其他服务实例具有相同的配置和代码库
  • 可伸缩 —— 使用异步处理和事件来最小化服务之间的直接依赖关系。

本书涵盖一下 6 类微服务模式

  • 核心微服务开发模式
  • 微服务路由模式
  • 微服务客户端弹性模式
  • 微服务安全模式
  • 微服务日志记录和跟踪模式
  • 微服务构建和部署模式

1.9.1 核心微服务开发模式

核心微服务开发模式解决了构建微服务的基础问题。

(1)服务粒度 —— 服务粒度过于粗粒度,在不同的业务问题领域重叠,会使服务随着时间的推移变得难以维护。服务职责过于细粒度,则会使应用程序的整体复杂性增加,并将服务变为无逻辑的(除了访问数据存储所需的逻辑)“哑”数据抽象层。
(2)通信协议 —— 使用XML、JSON或诸如 Thrift之类的二进制协议来与微服务传输数据。JSON是微服务的理想选择,并且JSON已经成为向微服务发送和接收数据的最常见选择
(3)接口设计 —— 如何设计实际的服务接口,便于开发人员进行服务调用?如何构建服务URL来传达服务意图?如何版本化服务?精心设计的微服务接口使服务变得更直观。
(4)服务的配置管理 —— 在不同云环境之间移动时,不必更爱核心应用程序代码或配置
(5)服务之间事件处理 —— 如何用事件解耦微服务,以便最小化服务之间硬编码的关系,并提高应用程序的弹性。

微服务不只是编写代码(微服务模式)

1.9.2 微服务路由模式

微服务路由模式负责处理希望消费微服务的客户端应用程序,使客户端应用程序发现服务的位置并路由到服务。

在基于云的应用程序中,可能会运行成百上千个微服务实例。需要抽象这些服务的物理IP地址,并为服务调用提供单个入口点,以便为所有服务调用持续强制安全和内容策略

服务发现和路由回答了这个问题:如何将客户的服务发送到服务的特定实例?

  • 服务发现 —— 如何使微服务变得可以被发现,以便客户端应用程序在不需要将服务的位置硬编码应用程序的情况下找到它们?如何确保从可用的服务实例池中删除表现不佳的微服务实例。
  • 服务路由 —— 如何为所有服务提供单个入口点,以便将安全策略和路由规则统一应用于微服务应用程序中的多个服务和服务实例

服务发现和服务路由并不彼此依赖。

服务发现和路由是所有大规模微服务应用的关键部分

服务发现从客户端抽象出服务的物理位置。可以添加新的微服务实例来进行扩大,并且可以透明地从服务中删除不健康的服务实例

服务路由为微服务客户端提供了单一的逻辑URL来进行通信,并作为授权、验证和内容检查等内容策略的实施点

微服务不只是编写代码(微服务模式)

1.9.3 微服务客户端弹性模式

因为微服务架构是高度分布式的,所以必须对如何防止单个服务(或服务实例)中的问题级联暴露给服务的消费者时分敏感。

这里介绍四种客户端弹性模式

  • 客户端负载均衡 —— 在服务客户端上缓存服务实例的位置,以便对微服务的多个实例的调用负载均衡到该微服务的所有健康实例(Ribbon)
  • 断路器模式 —— 阻止客户急需调用出现故障的或遭遇性能问题的服务。如果服务运行缓慢,客户端调用时会消耗它的资源。开发人员希望出现故障的微服务调用能够快速失败,以便主叫客户端可以快速响应并插曲适当的措施。(Hystrix)
  • 后备模式 —— 当服务调用失败,提供插件机制,允许服务的客户端尝试通过调用微服务之外的其他方法来执行工作。(Hystrix fallback)
  • 舱壁模式 —— 微服务应用程序使用多个分布式资源来执行工作。如何区分这些调用,以便表现不佳的服务调用不会对应用程序的其他部分产生负面影响(Docker)。

微服务不只是编写代码(微服务模式)
微服务不只是编写代码(微服务模式)

1.9.4 微服务安全模式

微服务的三种安全模式

  • 验证 —— 确定服务的客户端就是它们声称的那个主体
  • 授权 —— 确定调用微服务的客户单是否允许执行它们正在进行的操作。
  • 凭证管理和传播 —— 避免客户端每次都要提供凭证信息才能访问事务中涉及的服务调用。使用基于令牌的安全标准来获取可以从一个服务调用传递到另一个服务调用令牌,以验证和授权用户,这里设计的标准包括 OAuth2和JSON Web Token(JWT)。

使用基于令牌的安全方案,可以实现服务验证和授权,而无需传递客户端凭证

微服务不只是编写代码(微服务模式)

1.9.5 微服务日志记录和跟踪模式

微服务架构的有点是单体应用被分解成可以彼此独立部署的小的功能部件,而它的缺点是调试和跟踪应用程序和服务中发生的事情要困难地多。

三种核心日志记录和跟踪模式。

  • 日志关联 —— 一个用户事务会调用多个服务,需要将这些服务所生成的日志关联到一起。关联(correlation)ID,这是一个唯一的标识符,在事务中调用所有服务都会携带他,通过它能够将每个服务生成的日志条目联系起来。
  • 日志聚合 —— 将微服务(及其各个实例)生成的所有日志合并到一个可查询的数据库中及如何使用关联ID来协助搜索聚合日志。
  • 微服务跟踪 —— 在涉及的所有服务中可视化客户端事务的流程,并了解事务所涉及的服务的性能特征

微服务不只是编写代码(微服务模式)

1.9.6 微服务构建和部署模式

微服务架构的核心原则之一是,微服务的每个实例都应该和其他所有实例相同。“配置漂移”(某些文件在部署到服务器之后发生了一些变化)是不允许出现的

一句常说的话

“我在交付准备服务器上只做了一个小小的改动,但是我忘了在生产服务器中也做这样的改动。”许多宕机系统的解决方案通常是从开发人员或系统管理员的这句话开始的。

微服务的小规模与有限范围的特点可以将 “不可变基础设施”概念引入组织:一旦部署服务,其运行的基础设施就再也不会被人触碰。

不可变基础设施是成功使用微服务架构的关键因素,因为在生产中必须要保证开发人员为特定微服务启动的每个微服务实例与其他微服务实例相同。

在构建过程中构建和编译微服务并准备进行微服务的虚拟微服务镜像。部署微服务时,服务器运行所需的整个机器镜像都会进行部署。

微服务不只是编写代码(微服务模式)

  • 构建和部署管道 —— 创建一个可重复的构建和部署过程,只需一键即可构建和部署到组织中的任何环境
  • 基础设施即代码 —— 将服务的基础设施作为可在源代码管理下执行和管理的代码去对待。
  • 不可变服务器 —— 一旦创建了微服务镜像,如何确保它在部署之后永远不会改变
  • 凤凰服务器(Phoenix Server) —— 服务运行的时间越长,就越容易发生配置漂移。如何确保运行微服务的服务器定期被拆卸,并重新创建一个不可变的镜像。

使用这些模式和主题的目的是,在配置漂移影响到上层环境(如交付准备环境或生产环境)之前,尽可能地公开并消除配置漂移。