- 内容提要
- 译者序
- 前言
- 第 1 章 欢迎迈入云世界,Spring
- 第 2 章 使用 Spring Boot 构建微服务
- 第 3 章 使用 Spring Cloud 配置服务器控制配置
- 第 4 章 服务发现
- 第 5 章 使用 Spring Cloud 和 Netflix Hystrix 的客户端弹性模式
- 第 6 章 使用 Spring Cloud 和 Zuul 进行服务路由
- 第 7 章 保护微服务
- 第 8 章 使用 Spring Cloud Stream 的事件驱动架构
- 第 9 章 使用 Spring Cloud Sleuth 和 Zipkin 进行分布式跟踪
- 第 10 章 部署微服务
- 附录 A 在桌面运行云服务
- 附录 B OAuth2 授权类型
1.9 微服务不只是编写代码
尽管构建单个微服务的概念很易于理解,但运行和支持健壮的微服务应用程序(尤其是在云中运行)不只是涉及为服务编写代码。编写健壮的服务需要考虑几个主题。图 1-7 强调了这些主题。
图 1-7 微服务不只是业务逻辑,还需要考虑服务的运行环境以及服务的伸缩性和弹性
下面我们来更详细地了解一下图 1-7 中提及的要点。
- 大小适当 ——如何确保正确地划分微服务的大小,以避免微服务承担太多的职责?请记住,适当的大小允许快速更改应用程序,并降低整个应用程序中断的总体风险。
- 位置透明 ——在微服务应用程序中,多个服务实例可以快速启动和关闭时,如何管理服务调用的物理细节?
- 有弹性 ——如何通过绕过失败的服务,确保采取“快速失败”的方法来保护微服务消费者和应用程序的整体完整性?
- 可重复 ——如何确保提供的每个新服务实例与生产环境中的所有其他服务实例具有相同的配置和代码库?
- 可伸缩 ——如何使用异步处理和事件来最小化服务之间的直接依赖关系,并确保可以优雅地扩展微服务?
本书采用基于模式的方法来回答这些问题。通过基于模式的方法,本书列出可以跨不同技术实现来使用的通用设计。虽然本书选择了使用 Spring Boot 和 Spring Cloud 来实现本书中所使用的模式,但开发人员完全可以把这些概念和其他技术平台一起使用。具体来说,本书涵盖以下 6 类微服务模式:
- 核心微服务开发模式;
- 微服务路由模式;
- 微服务客户端弹性模式;
- 微服务安全模式;
- 微服务日志记录和跟踪模式;
- 微服务构建和部署模式。
让我们深入了解一下这些模式。
1.9.1 核心微服务开发模式
核心微服务开发模式解决了构建微服务的基础问题,图 1-8 突出了我们将要讨论的基本服务设计的主题。
图 1-8 在设计微服务时必须考虑服务是如何通信以及被消费的
- 服务粒度 ——如何将业务域分解为微服务,使每个微服务都具有适当程度的职责?服务职责划分过于粗粒度,在不同的业务问题领域重叠,会使服务随着时间的推移变得难以维护。服务职责划分过于细粒度,则会使应用程序的整体复杂性增加,并将服务变为无逻辑的(除了访问数据存储所需的逻辑)“哑”数据抽象层。第 2 章将会介绍服务粒度。
- 通信协议 ——开发人员如何与服务进行通信?使用 XML(Extensible Markup Language,可扩展标记语言)、JSON(JavaScript 对象表示法)或诸如 Thrift 之类的二进制协议来与微服务传输数据?本书将介绍为什么 JSON 是微服务的理想选择,并且 JSON 已成为向微服务发送和接收数据的最常见选择。第 2 章将会介绍通信协议。
- 接口设计 ——如何设计实际的服务接口,便于开发人员进行服务调用?如何构建服务 URL 来传达服务意图?如何版本化服务?精心设计的微服务接口使服务变得更直观。第 2 章将会介绍接口设计。
- 服务的配置管理 ——如何管理微服务的配置,以便在不同云环境之间移动时,不必更改核心应用程序代码或配置?第 3 章将会介绍管理服务配置。
- 服务之间的事件处理 ——如何使用事件解耦微服务,以便最小化服务之间的硬编码依赖关系,并提高应用程序的弹性?第 8 章将会介绍服务之间的事件处理。
1.9.2 微服务路由模式
微服务路由模式负责处理希望消费微服务的客户端应用程序,使客户端应用程序发现服务的位置并路由到服务。在基于云的应用程序中,可能会运行成百上千个微服务实例。需要抽象这些服务的物理 IP 地址,并为服务调用提供单个入口点,以便为所有服务调用持续强制执行安全和内容策略。
服务发现和路由回答了这个问题:如何将客户的服务请求发送到服务的特定实例?
- 服务发现 ——如何使微服务变得可以被发现,以便客户端应用程序在不需要将服务的位置硬编码到应用程序的情况下找到它们?如何确保从可用的服务实例池中删除表现不佳的微服务实例?第 4 章将会介绍服务发现。
- 服务路由 ——如何为所有服务提供单个入口点,以便将安全策略和路由规则统一应用于微服务应用程序中的多个服务和服务实例?如何确保团队中的每位开发人员不必为他们的服务提供自己的服务路由解决方案?第 6 章将会介绍服务路由。在图 1-9 中,服务发现和服务路由之间似乎具有硬编码的事件顺序(首先是服务路由,然后是服务发现)。然而,这两种模式并不彼此依赖。例如,我们可以实现没有服务路由的服务发现,也可以实现服务路由而无需服务发现(尽管这种实现更加困难)。
图 1-9 服务发现和路由是所有大规模微服务应用的关键部分
1.9.3 微服务客户端弹性模式
因为微服务架构是高度分布式的,所以必须对如何防止单个服务(或服务实例)中的问题级联暴露给服务的消费者十分敏感。为此,这里将介绍 4 种客户端弹性模式。
- 客户端负载均衡 ——如何在服务客户端上缓存服务实例的位置,以便对微服务的多个实例的调用负载均衡到该微服务的所有健康实例?
- 断路器模式 ——如何阻止客户继续调用出现故障的或遭遇性能问题的服务?如果服务运行缓慢,客户端调用时会消耗它的资源。开发人员希望出现故障的微服务调用能够快速失败,以便主叫客户端可以快速响应并采取适当的措施。
- 后备模式 ——当服务调用失败时,如何提供“插件”机制,允许服务的客户端尝试通过调用微服务之外的其他方法来执行工作?
- 舱壁模式 ——微服务应用程序使用多个分布式资源来执行工作。如何区分这些调用,以便表现不佳的服务调用不会对应用程序的其他部分产生负面影响?
图 1-10 展示了这些模式如何在服务表现不佳时,保护服务消费者不受影响。第 5 章将会介绍这些主题。
图 1-10 使用微服务时,必须保护服务调用者远离表现不佳的服务。记住,
慢速或无响应的服务所造成的中断并不仅仅局限于直接关联的服务
1.9.4 微服务安全模式
写一本微服务的书绕不开微服务安全性。在第 7 章中我们将介绍 3 种基本的安全模式。这 3 种模式具体如下。
- 验证 ——如何确定调用服务的客户端就是它们声称的那个主体?
- 授权 ——如何确定调用微服务的客户端是否允许执行它们正在进行的操作?
- 凭据管理和传播 ——如何避免客户端每次都要提供凭据信息才能访问事务中涉及的服务调用?具体来说,本书将介绍如何使用基于令牌的安全标准来获取可以从一个服务调用传递到另一个服务调用的令牌,以验证和授权用户,这里涉及的标准包括 OAuth2 和 JSON Web Token(JWT)。
图 1-11 展示了如何实现上述 3 种模式来构建可以保护微服务的验证服务。
图 1-11 使用基于令牌的安全方案,可以实现服务验证和授权,而无需传递客户端凭据
本书现在不会太深入图 1-11 中的细节。需要一整章来介绍安全是有原因的(实际上它本身就可以是一本书)。
1.9.5 微服务日志记录和跟踪模式
微服务架构的优点是单体应用程序被分解成可以彼此独立部署的小的功能部件,而它的缺点是调试和跟踪应用程序和服务中发生的事情要困难得多。
因此,本书将介绍以下 3 种核心日志记录和跟踪模式。
- 日志关联 ——一个用户事务会调用多个服务,如何将这些服务所生成的日志关联到一起?借助这种模式,本书将会介绍如何实现一个关联(correlation)ID,这是一个唯一的标识符,在事务中调用所有服务都会携带它,通过它能够将每个服务生成的日志条目联系起来。
- 日志聚合 ——借助这种模式,我们将会介绍如何将微服务(及其各个实例)生成的所有日志合并到一个可查询的数据库中。此外,本书还会研究如何使用关联 ID 来协助搜索聚合日志。
- 微服务跟踪 ——最后,我们将探讨如何在涉及的所有服务中可视化客户端事务的流程,并了解事务所涉及的服务的性能特征。
图 1-12 展示了这些模式如何配合在一起。第 9 章中将会更加详细地介绍日志记录和跟踪模式。
图 1-12 一个深思熟虑的日志记录和跟踪策略使跨多个服务的调试事务变得可管理
1.9.6 微服务构建和部署模式
微服务架构的核心原则之一是,微服务的每个实例都应该和其他所有实例相同。“配置漂移”(某些文件在部署到服务器之后发生了一些变化)是不允许出现的,因为这可能会导致应用程序不稳定。
一句经常说的话
“我在交付准备服务器上只做了一个小小的改动,但是我忘了在生产服务器中也做这样的改动。”多年来,我在紧急情况团队中工作时,许多宕机系统的解决方案通常是从开发人员或系统管理员的这些话开始的。工程师(和大多数人一般)是以良好的意图在操作。工程师并不是故意犯错误或使系统崩溃,相反,他们尽可能做到最好,但他们会变得忙碌或者分心。他们调整了一些服务器上的东西,打算回去在所有环境中做相同的调整。
在以后某个时间点里,出现了中断状况,每个人都在搔头挠耳,想要知道其他环境与生产环境之间有什么不同。我发现,微服务的小规模与有限范围的特点创造了一个绝佳机会——将“不可变基础设施”概念引入组织:一旦部署服务,其运行的基础设施就再也不会被人触碰。
不可变基础设施是成功使用微服务架构的关键因素,因为在生产中必须要保证开发人员为特定微服务启动的每个微服务实例与其他微服务实例相同。
为此,本书的目标是将基础设施的配置集成到构建部署过程中,这样就不再需要将软件制品(如 Java WAR 或 EAR)部署到已经在运行的基础设施中。相反,开发人员希望在构建过程中构建和编译微服务并准备运行微服务的虚拟服务器镜像。部署微服务时,服务器运行所需的整个机器镜像都会进行部署。
图 1-13 阐述了这个过程。本书最后将介绍如何更改构建和部署管道,以便将微服务及运行的服务器部署为单个工作单元。第 10 章将介绍以下模式和主题。
图 1-13 开发人员希望微服务及其运行所需的服务器成为在不同环境间作为整体部署的原子制件
- 构建和部署管道 ——如何创建一个可重复的构建和部署过程,只需一键即可构建和部署到组织中的任何环境?
- 基础设施即代码 ——如何将服务的基础设施作为可在源代码管理下执行和管理的代码去对待?
- 不可变服务器 ——一旦创建了微服务镜像,如何确保它在部署之后永远不会更改?
- 凤凰服务器 (Phoenix server)——服务器运行的时间越长,就越容易发生配置漂移。如何确保运行微服务的服务器定期被拆卸,并重新创建一个不可变的镜像?
使用这些模式和主题的目的是,在配置漂移影响到上层环境(如交付准备环境或生产环境)之前,尽可能快地公开并消除配置漂移。
注意
本书中的代码示例(除了第 10 章)都将在本地机器上运行。前两章的代码可以直接从命令行运行,从第 3 章开始,所有代码将被编译并作为 Docker 容器运行。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论