第 8 章 响应式 Spring:韧性和可扩展性

本章内容:

  • 使用 Reactor 和 Spring 实现异步非阻塞架构
  • 使用 Spring WebFlux 和 Spring Data R2DBC 构建响应式服务器
  • 使用 Spring WebClient 构建响应式客户端
  • 使用响应式 Spring 构建弹性应用程序
  • 使用 Spring、Reactor 和 Testcontainers 测试响应式应用程序

Polarsophia——Polar Bookshop 背后的组织——对其新软件产品的进展非常满意。其使命是传播关于北极和北极圈的知识和认知,而将其图书目录向全世界开放是实现这一使命的重要组成部分。

目前构建的 Catalog Service 应用程序是一个良好的起点。它满足了浏览和管理图书的需求,并遵循云原生模式和实践。它是自包含且无状态的,使用数据库作为支持服务来存储状态,可通过环境变量或配置服务器进行外部配置,尊重环境一致性,并通过作为部署管道一部分的自动化测试执行进行验证,遵循持续交付实践。为了最大程度的可移植性,它还被容器化,并可以使用服务发现、负载均衡和复制等原生功能部署到 Kubernetes 集群。

系统的另一个重要功能是购买书籍。在本章中,您将开始处理 Order Service 应用程序。这个新组件不仅与数据库交互,还会与 Catalog Service 交互。当应用程序大量依赖 I/O 操作(如数据库调用或与其他服务的 HTTP 请求/响应通信)时,Catalog Service 中使用的每请求线程(thread-per-request)模型开始暴露其技术限制。

在每请求线程模型中,每个请求都绑定到专门分配给其处理的线程。如果数据库或服务调用是处理的一部分,线程将发出请求然后阻塞,等待响应。在空闲时间,分配给该线程的资源被浪费,因为它们不能用于其他任何事情。响应式编程范式解决了这个问题,并提高了所有 I/O 密集型应用程序的可扩展性、弹性和成本效益。

响应式应用以异步和非阻塞方式运行,意味着计算资源被更有效地利用。这在云中是一个巨大优势,因为您只需为所用部分付费。当线程向支持服务发出调用时,它不会空闲等待,而是继续执行其他操作。这消除了线程数与并发请求数之间的线性依赖关系,从而实现更具可扩展性的应用。在相同的计算资源下,响应式应用可以比非响应式应用服务更多用户。

云原生应用是部署在动态环境中的高度分布式系统,变化是常态,故障会且必将发生。如果服务不可用怎么办?如果请求在到达目标服务的途中丢失怎么办?如果响应在返回调用方的途中丢失怎么办?我们能在此上下文中保证高可用性吗?

弹性(Resilience)是迁移到云的目标之一,也是云原生应用的特征属性之一。我们的系统应该对故障具有弹性,并足够稳定以确保向用户提供一定的服务水平。网络上的服务间集成点是实现生产环境稳定和弹性系统的最关键领域之一。这一点如此重要,以至于 Michael T. Nygard 在其著作 Release It! Design and Deploy Production-Ready Software(Pragmatic Bookshelf, 2018)中花了大量篇幅讨论该主题。

本章将聚焦于使用响应式范式为云构建弹性、可扩展和高效的应用。首先介绍事件循环模型以及 Reactive Streams、Project Reactor 和 Spring 响应式栈的主要特性。然后使用 Spring WebFlux 和 Spring Data R2DBC 构建响应式 Order Service 应用。

Order Service 将与 Catalog Service 交互以检查图书的可用性和详细信息,因此您将看到如何使用 Spring WebClient 实现响应式 REST 客户端。两个服务之间的集成点是需要额外关注的区域,以实现稳健性和容错性。依托 Reactor 项目,您将采用重试、超时和降级等稳定性模式。最后,您将编写自动化测试,使用 Spring Boot 和 Testcontainers 验证响应式应用的行为。

NOTE 本章的示例源代码可在 Chapter08/08-begin 和 Chapter08/08-end 文件夹中找到,包含项目的初始和最终状态(https://github.com/ThomasVitale/cloud-native-spring-in-action)。

results matching ""

    No results matching ""