前言

开发分布式系统具有挑战性。复杂性从应用程序层转移到网络层,并要求各个服务之间更密切的交互。将代码设计为“云原生”意味着要处理 12 要素(12-factor)的问题,例如外部配置、无状态性、日志记录以及与后端服务的连接。Spring Cloud 项目套件中包含了许多服务,可以使应用程序在云环境中运行。

架构图

  1. 多端适配,物联网、手机、电脑设备通过网关访问服务。
  2. 网关使用配置中心获取配置,通过服务注册中心发现调用微服务。
  3. 服务运行时进行分布式追踪。

组件选型

服务发现

通过服务发现组件可以监控服务的部署和存活情况,并实现基于服务编码的负载均衡进行远程调用。以下是一些常见的服务发现工具:

  • Netflix Eureka:已停止维护,不再推荐使用。
  • HashiCorp Consul:提供了强大的服务发现和配置管理功能。
  • Zookeeper:在从 Eureka 切换过来时成本较低,并且功能相对简单。推荐
  • Nacos:功能完善,提供了用户界面(UI),易于管理和监控。推荐

接口网关

多端调用和微服务部署可能会导致系统变得复杂。通过 API 网关调用多个服务可以减少系统的复杂程度。API 网关能够提供安全拦截处理、路由信息传递、隐藏服务、负载均衡等功能。

在选择 API 网关时,有几个常用的框架可供选择:

  • Spring Cloud Gateway:这是一个基于 Spring Cloud 生态系统的 API 网关,它提供了丰富的功能,如路由、过滤器、负载均衡等。Spring Cloud Gateway 具有良好的扩展性和灵活性。推荐
  • Zuul:这是一个早期的 API 网关框架,由 Netflix 开发。然而,需要注意的是,Zuul 已经停止维护,不再推荐使用。

除了 Spring Cloud Gateway 和 Zuul 之外,还有其他一些 API 网关框架,如 Kong、Tyk、APISIX 等。

云服务配置

在微服务中,配置嵌入到应用侧有很多限制。例如不能实时更新、更新配置需要重启、版本维护没有、多环境支持。配置中心主要解决的就是这些问题。

  • Spring Cloud Config,分布式部署、支持注册中心、版本控制等。推荐。
  • Nacos,提供 UI 可视化界面。也支持分布式部署、支持注册中心、版本控制等。推荐。

熔断

当分布式系统中出现服务不可靠的情况时,熔断器可以帮助解决这个问题。熔断器可以采用限流、降级、重试等机制来处理服务不可靠的情况。

  • Resilience4J:这是一个轻量级的熔断器框架,它提供了限流、降级和重试等功能。Resilience4J 易于使用和配置。推荐
  • Sentinel:这是一个强大的熔断器和限流框架,它支持多种限流策略,并提供了丰富的监控和指标功能。推荐
  • Hystrix:这是一个经典的熔断器框架,由 Netflix 开发。Hystrix 提供了断路器、降级和缓存等功能。

服务追踪

调试分布式应用确实是一项复杂且耗时的任务。当问题出现时,可能会涉及到多个独立的微服务。Sleuth 提供了一系列服务调用追踪的集成方案,使得服务追踪更加可预测和可重复。

需要注意的是,Sleuth 已经停止对 Spring Boot 3 的支持,而后续的替代者是 Micrometer Tracing。Micrometer Tracing 提供了类似的接口和功能。

  • Micrometer Tracing:作为 Sleuth 的后继者,Micrometer Tracing 提供了更强大和灵活的追踪功能。推荐
  • Zipkin:这是一个开源的分布式追踪系统,它可以收集和可视化服务之间的调用关系。
  • Skywalking:这是一个功能丰富的分布式追踪和监控系统,它提供了全面的监控和分析功能。推荐

测试集成

想要拥有可靠、值得信赖和稳定的 API,就得需要单元测试。合同式测试是高效团队常用的一种技术,它通过将 API 的内容形式化并构建相关测试,来帮助确保代码或者 API 是正常运行功能正常的。需要注意的是,Spring Cloud Contract 已经停止维护了。在选择测试框架时,推荐使用 JUnit 5(Spring Boot Test)。JUnit 5 是一个广泛使用的单元测试框架,与 Spring Boot 集成良好,可以方便地进行测试编写和执行。

  • Spring Cloud Contract 停止维护了
  • Junit 5(Spring boot test)可以编写针对 API 的测试用例,验证 API 的响应结果是否符合预期。通过模拟请求和响应,可以对 API 进行全面的测试,包括参数验证、响应状态码、数据返回等。推荐

远程调用

在微服务架构中,存在许多独立的单体服务,服务之间的调用频率增加,依赖关系也变得更加复杂。为了解决这些问题,我们需要一个通用的框架来处理服务之间的调用,并解决负载均衡、安全机制、服务降级等一系列问题。

OpenFeign 是一个非常流行和强大的框架,用于在微服务之间进行调用。它提供了简洁而易于使用的 API,使开发者能够方便地调用其他服务。OpenFeign 支持负载均衡、熔断器、重试机制等功能,以提高系统的可靠性和容错性。

使用 OpenFeign,你可以通过注解或配置来定义服务接口和调用方式,然后框架将自动处理服务的发现、调用和异常处理。它还支持动态路由和参数传递,可以轻松实现服务之间的通信。
OpenFeign 与其他微服务框架(如 Spring Cloud)集成良好,可以与注册中心(如 Eureka)配合使用,实现服务的自动注册和发现。

  • OpenFeign,推荐

接口文档

通过统一的接口文档管理,可以减少接口模拟、接口测试、接口文档输出等相关工作。

  • springdoc-openapi,推荐,支持 springboot 3 生态,支持 openapi3
  • springfox(前身 swagger-springmvc) ,不推荐,缺少 openapi 3 的支持

分布式事务

分布式事务是指在分布式系统中,跨多个节点或多个数据库的操作需要保持一致性和原子性的一种机制。在传统的单节点事务中,事务在一个数据库上执行,而在分布式事务中,事务可能涉及多个数据库或多个服务之间的操作。

分布式事务面临的挑战主要是协调和保持数据的一致性。由于涉及多个节点或多个数据库,事务的执行会面临以下问题:

  • ACID 属性的保持:分布式事务需要满足 ACID(原子性、一致性、隔离性、持久性)属性,即要么所有操作都成功,要么都失败。这需要确保在不同节点或数据库上的操作都能同步进行,并且在出现故障时能够回滚。
  • 并发控制:由于分布式事务可能涉及多个并发执行的操作,需要对并发访问进行控制,以避免数据的不一致性。常见的并发控制方法包括锁机制、多版本并发控制(MVCC)等。
  • 故障处理:在分布式环境下,各个节点或数据库可能出现故障或网络通信中断,这可能导致事务的中断或数据不一致。因此,需要有效的故障处理机制,如故障恢复、重试机制等。

为了解决这些问题,有多种分布式事务协调协议被提出,包括两阶段提交(2 PC)、三阶段提交(3 PC)、Paxos、Raft 等。这些协议通过协调参与者节点的行为,保证了分布式事务的一致性和原子性。此外,还有一些分布式事务的替代方案,如基于消息队列的最终一致性、补偿事务等。这些方案在一定程度上降低了分布式事务的复杂性和性能开销,但也带来了一些其他的约束和问题。

分布式事务是在分布式系统中保持一致性和原子性的重要机制,需要采用合适的协调协议和方案来解决数据的一致性和并发控制的问题。

  • Seata,推荐,是由阿里中间件团队发起的开源项目 Fescar,后更名为 Seata,它是一个是开源的分布式事务框架。以高效并且对业务 0 侵入的方式解决微服务场景下面临的分布式事务问题,它目前提供 AT 模式 (即 2 PC) 及 TCC 模式的分布式事务解决方案。

组件确定

通过 SpringCloudAlibaba、SpringCloud 的组件推荐选型,SpringCloud 2023 最终组件选型如下:

  • 注册中心(Spring Cloud Zookeeper):负责服务的注册和发现。
  • 网关(Spring Cloud Gateway):作为外部请求的入口,实现路由和负载均衡。
  • 云服务配置(Spring Cloud Config):用于管理服务的配置信息。
  • 熔断(Sentinel):提供熔断器功能,实现服务的限流和降级。
  • 服务追踪(Micrometer Tracing):用于追踪和监控服务的性能和调用情况。
  • 测试集成(JUnit 5 + Spring Boot Test):用于编写和执行单元测试。
  • 远程调用(OpenFeign):用于服务之间的远程调用。
  • 接口文档(springdoc-openapi + openapi 3):用于生成和管理 API 的文档。
  • 分布式事务(Seata):用于处理跨多个服务的事务。

这些组件通过相互协作,构建了一个完整的微服务架构,实现了服务的注册、发现、配置管理、熔断器、服务追踪、测试集成、远程调用和接口文档生成等功能。每个组件在整个架构中扮演着不同的角色,共同确保了微服务系统的可靠性、可扩展性和高可用性。