distributed microservice
分布式与微服务的定义及关系;分布式微服务架构里的各组件,如:配置中心、服务注册/发现、服务网关、负载均衡器、限流降级、断路器、服务调用、分布式事务等;spring cloud 介绍及实现案例,如:spring cloud netflix(eureka、ribbon、feign、hystrix、zuul)、spring cloud alibaba(nacos、sentinel、seata、schedulex、rocket mq、sidecar)等。
------ 2025 年 1 月 5 日 甲辰年腊月初六 小寒
版本
- jdk: 17
- spring boot: 3.3.6
- spring cloud: 4.1.2
- spring cloud alibaba: 2023.0.1.2
目录
-
- [distributed microservice](#distributed microservice)
-
- [1 分布式与微服务](#1 分布式与微服务)
-
- [1.1 分布式](#1.1 分布式)
- [1.2 微服务](#1.2 微服务)
- [2 分布式微服务系统](#2 分布式微服务系统)
-
- [2.1 配置中心](#2.1 配置中心)
- [2.2 注册中心](#2.2 注册中心)
- [2.3 网关](#2.3 网关)
- [2.4 调用](#2.4 调用)
- [2.5 负载均衡](#2.5 负载均衡)
- [2.6 限流、降级和熔断](#2.6 限流、降级和熔断)
- [2.7 分布式事务](#2.7 分布式事务)
- [3 spring cloud](#3 spring cloud)
-
- [3.1 简介定义](#3.1 简介定义)
- [3.2 版本命名](#3.2 版本命名)
- [3.3 实现案例(netflix & alibaba)](#3.3 实现案例(netflix & alibaba))
- [3.4 nacos 与 eureka 的区别](#3.4 nacos 与 eureka 的区别)
- [3.5 gateway 与 zuul 的区别](#3.5 gateway 与 zuul 的区别)
1 分布式与微服务
分布式:分散的是压力;微服务:分散的是能力。这句话并非绝对地定义了分布式与微服务,而是我们可以从这个角度来区别二者。
微服务架构是分布式架构的一种解决方案。因此,微服务架构是分布式架构,但分布式架构不一定是微服务架构。
1.1 分布式
分布式是计算机科学中的一个研究方向,它研究如何把一个需要巨大计算能力或资源才能解决的问题分成若干个小部分,然后把这些部分分配给多个计算机进行处理,最后把这些结果综合起来得到最终结果。即分散压力。换言之,当程序和数据需要通过网络分布在多个计算机上时,我们就称它是分布式的。如分布式计算、分布式存储、分布式数据、分布式缓存、分布式文件系统等。
分布式系统的主要目标(优点)和缺点如下:
- 主要目标(优点):
- 高并发:分布的目的就是为了突破单节点性能屏障。
- 高性能:分散了压力,各节点的处理速度将只受限于硬件的性能。
- 高可用:多节点避免了单节点故障导致系统不可用。
- 可扩展:可通过水平增加或删除节点的方式应对不同计算场景。
- . . .
- 缺点:
- 复杂度增加:由于程序和数据的分布性,设计开发时则需要考虑网络通信、数据一致性和故障处理等问题。
- 数据一致性:由于存在多节点,故需要考虑各节点间的数据一致性。
- 性能问题:由于各节点间需要通过网络通信,网络会有些许延迟,故对性能有一定影响。
- 故障排查难度增加:在分布式系统中,数据可能会流转在多个节点,当出现故障时,则需要考虑多个节点的交互。
- 部署和维护成本增加:由于多节点,则会增加部署、维护和监控的成本。
- . . . (尽管它存在这些缺点,但它带来的收益却是不可估量的!)
与分布式对应的是集中式,二者区别如下:
- 直观区别:集中式中程序、数据和资源等集中在中心节点上,中心节点来处理计算任务。而分布式则将这些分布在多个节点上,且每个节点都可以处理计算任务。
- 集中式的优点为系统复杂度低,不用考虑数据一致性,故障排查难度低,部署和维护成本低;缺点为:可靠性差、性能受限于硬件性能,扩展性低。
1.2 微服务
微服务是一种架构风格,是分布式架构的一种解决方案,其由 soa 架构演变而来。其作用是将一个大型应用以业务为界限划分成多个小型应用,每个小型服务独立设计开发、测试维护,且都具备独立的自制能力。即分散能力。其具有以下特点:
- 服务拆分:微服务最重要就是服务拆分,如按业务拆分等。拆分维度和粒度是关键。
- 松耦合:服务拆分后,将以微服务为单位进行设计开发、测试部署和运行维护,各服务之间通过轻量级的通信机制通信。同时,每个服务单独演化,将影响范围缩小至该服务对应的业务内,提高了系统的可用性。
- 可扩展性:可根据不同服务对应的业务场景,来动态增加/删除该服务对应的节点数量,以应对不同的流量场景。
总之,分布式是一种思想,微服务也是一种思想,两者有互通之处,因为微服务更偏向于落地,所以可以把微服务架构理解为分布式架构的一种解决方案;又因为分布式架构的应用范围更广,微服务架构是分布式架构,但分布式架构不一定是微服务架构。常见的如 kafka、flink、spark、redis、bigtable、fastdfs、minio、zookeeper 等都是分布式系统。常见的 web 领域的大型系统大多都可以理解为微服务系统,当然,你也可以称它是分布式的。
2 分布式微服务系统
如下图所示,一个简单的分布式微服务系统架构图大概长这样。访问者可以是移动端、PC 端和其它服务等;nginx 作为整个系统对外入口网关;服务网关作为系统中所有服务的统一入口(后文会说明 nginx 网关与服务网关的区别);注册配置中心用来配置和管理各服务;各服务之间可通过 http、rpc 调用;服务间调用可通过负载均衡来调配资源;可通过限流、熔断来进行服务流量控制和服务保护;同时也需要支持分布式事务;当然在数据存储方面也需要的分布式存储、缓存和消息队列等的支持。
分布式微服务系统中,常用组件有:配置中心、注册中心、网关、调用组件、负载均衡器、限流熔断(降级)组件和分布式事务组件等。其各组件作用及详细说明如下。
2.1 配置中心
顾名思义,配置中心的作用是为系统中各服务提供配置。单体应用中,配置通常和程序代码一起打包部署。而在分布式系统中,通常会存在多个应用,相对应的就会存在多个配置,显然配置和程序代码一起打包部署的方式不太合理,耗时费力(总不能每改动一次配置就要重新打包部署或重启服务吧,想想就觉得可怕)。配置中心通常以外部化的方式为应用提供配置。其优点如下:
- 便于管理配置:将配置外部化,只需通过可视化操作即可完成对应用配置的管理。
- 环境隔离:每个应用通常会存在开发、测试和生产等多个环境的配置,配置中心可方便切换不同环境配置。
- 提高程序安全性:将配置信息存储在代码库或应用程序文件中可能会被意外泄漏或恶意攻击,从而造成安全风险。通过配置中心可对配置信息进行加密保护,且可进行访问权限控制。
- 动态更新配置:配置信息之所以放在配置文件中是因为配置信息可能随改动,一般情况下,修改配置后需要重启应用以使配置生效。而配置中心则支持动态更新配置,即配置变更后不需要重启应用就可使配置生效。
2.2 注册中心
微服务与传统单体应用架构最大的区别就是强调软件模块的拆分。在单体应用架构下,一个应用内可能涵盖了系统的多个模块,这些模块会在一个进程内部署运行,模块之间的调用直接通过方法调用即可完成。但在微服务系统中,通常会根据系统的功能特点或业务逻辑,按照一定粒度的拆分后进行单独部署运行,以便实现模块内的高内聚。模块间的低耦合,实现整个微服务系统的高可扩展性。此时,就会出现不同模块间的跨进程跨主机调用。因此,如何让微服务系统能够像单体应用那样提供统一对外的服务调用能力,则成为微服务架构层面需要重点解决的问题之一。
如上图所示,通过在微服务系统中引入一个叫做注册中心的组件,来作为协调者。其大致原理为,所有微服务应用在启动时会将自身的服务名称、ip 地址和端口号等信息注册到注册中心,然后各服务在处理请求的过程中会根据服务名称到注册中心中查找对应服务的 ip 地址和端口号来进行服务间的调用(当然实际调用可能需要借助其它组件)。
2.3 网关
微服务系统中的网关主要有以下功能:
- 路由与负载均衡:可根据请求的目标地址和定义的路由规则将请求路由到合适的服务实例。同时可以使用负载均衡算法来均匀分配请求负载,以确保每个服务实例都能承担适当的负载。
- 认证与授权:可集中处理身份认证与授权问题。验证请求中的身份信息,确保只有经过授权的用户才可访问特定的服务。
- 安全性:可以通过安全策略来增加整个系统的安全性,以防止常见的攻击如 SQL 注入、跨站脚本,并对传输数据进行加密。
- 请求过滤与转换:可对请求进行预处理。如校验特定参数、转换请求格式和增加请求头等。通过统一处理重复的请求逻辑来减轻各个微服务的负担。
- 监控与日志:可记录请求和响应信息,以便故障排查和性能优化;同时可实时监控各个服务的运行状态,以便及时发现并处理异常情况。
nginx 网关与微服务网关的区别:
- 首先,nginx 通常作为独立的服务部署在网络入口(如客户端与服务端之间),而微服务网关通常作为整个服务集群的入口。
- 其次,nginx 主要提供高性能的代理和负载均衡功能。一般作为初级网关将流量分发到微服务网关集群。
- 然后,nginx 更为稳定但不便扩展;而微服务网关较为复杂但便于扩展。
- 最后,二者作为微服务系统中的重要节点,通常要求其具有极高的性能和极稳定的运行。
2.4 调用
微服务系统中各服务之间的调用通常有 http 和 rpc 两种方式。二者是两种不同的网络通信协议,它们在定义、用途、通信模式、数据传输格式、安全性和适用场景等方面存在显著区别,主要如下:
- 定义和用途:http 是一种应用层协议,或者试一个请求-响应协议,主要用于在 web 浏览器和服务器之间传输数据;rpc 是一种远程过程调用协议,允许程序调用另一个地址空间的过程或方法,就像这些过程和方法在本地一样,主要用于分布式系统中,特别是需要高性能和低延迟的场景下。
- 通信模式:http 是无状态协议,两个请求之间无直接联系,即意味着 http 的通信是不可靠的;rpc 则是有状态协议,客户端与服务器之间建立的是长连接,通信更加可靠。
- 数据传输格式:http 通常使用文本格式(如 json 或 xml)来传输数据,具有良好的可读性和可扩展性,但其体积较大故较耗时;rpc 使用二进制协议(如 protocol 或 thrift)来传输数据,虽然可读性和可扩展性较差,但体积小且效率高。
- 安全性:http 通常使用 SSL/TLS 协议来加密传输数据,以确保通信安全,但 http 协议本身在传输过程中容易被中间人攻击,导致数据泄露或篡改;rpc 同样支持加密和身份验证来确保通信安全,但其还提供了更加丰富的安全机制,如访问控制和签名等(http 也可以有访问控制和签名!(很大声那种!))。
- 适用场景:http 主要适用于浏览器和 web 应用程序之间的通信;rpc 主要用于分布式系统中,特别是高性能和低延迟的场景下。
看到这里你不会以为在微服务系统 rpc 一定优于 http 吧,显然不是!因为 rpc 有一个最大的缺点,即它要求调用方和提供方使用相同的技术或语言。这在很大程度上限制了其适用范围。
2.5 负载均衡
负载均衡是一种通过将网络流量均匀的分配到多个服务实例上,来提高系统性能和可用性的技术。它可以有效防止单点故障,并提升系统的响应速度。可从以下几个方面理解:
- 高可用性:当某个实例故障时,确保流量能够被其它实例接管,避免服务中断。
- 性能优化:可根据每个实例的软硬件条件来均匀分配流量,以避免某一实例过载,影响用户体验。
- 可扩展性:支持根据不同的流量情况,动态增加或减少服务实例。
常见的负载均衡策略如下:
- 轮询:将请求以此分发到每个实例。适用于请求处理时间相近的场景。
- 加权轮询:给每个实例分配权重,根据权重比例分发请求。适用于各实例性能(如网络、硬件等资源)差异较大的场景。
- 最少连接:将请求分发到当前连接数最少的实例上。适用于连接时间不均匀的场景。
- IP 哈希:根据请求源 ip 的哈希值来确定目标实例。适用于同一用户的请求始终需要同一实例处理的场景。
2.6 限流、降级和熔断
限流、降级和熔断是三种不同的系统稳定策略,它们在高并发场景下尤为重要。
-
限流:限流是一种控制系统并发流量的技术手段,通过限制请求频率或数量来防止系统过载或崩溃,以提高系统稳定性。限流是针对服务提供者的一种策略,可通过设定流量阈值并采取排队、拒绝请求或返回错误信息等方式来控制流量。
常见的限流算法有:
- 漏桶算法:请求先进入漏桶,再从漏桶中逐一取出进行处理,控制漏桶的流量。
- 令牌桶算法:请求会从令牌桶中得到一个令牌,然后处理,控制令牌桶中令牌的数量。
- 计数器算法:请求被计数,通过比较当前请求数与限流阈值来判断是否限流。
- 固定窗口限流算法:即设置单位时间内的请求数阈值,超过阈值的请求被拒绝掉,知道下一个窗口。
- 滑动窗口限流算法:将单位时间周期分为多个小周期,每个小周期内独立统计请求次数,过期的小周期会被删除。窗口内的小周期越多,限流统计就越精确。
-
降级:在系统过载时通过关闭非核心功能或当服务异常时响应默认值或备用值来保证服务的可用性。降级在服务提供端和消费端都可实现,如关闭核心功能等可在提供端实现(当然消费端也可以);服务提供端可能会因限流或异常不可用,此时则可在消费端做降级策略,如返回默认值等。
-
熔断:熔断是一种保护机制,用来保护因服务调用失败而引起的雪崩效应。熔断器在检测到服务调用失败达到一定阈值时,会暂时中断对该服务的调用,并在一定时间后尝试恢复。尤其是在分布式系统中,熔断显得尤为重要。分布式系统中为了保证系统的可用性和数据的一致性,会引入重试机制,重试机制可以解决实际问题,但同时也会带来其它问题。在高并发场景下,若某个服务或接口调用失败,则调用者会不断进行重试,这时候就会对服务造成二次伤害。但要注意,有些重试是无法避免的,如果为了避免雪崩效应而不适用重试机制,可能会因小失大。
2.7 分布式事务
首先,关于普通事务相关我们移步 史上最烂 spring transaction 原理分析 这篇文章。显而易见,在分布式微服务系统中的事务它就叫分布式事务。分布式事务具有分库分表、跨库和跨服务的特点,明显,传统的事务方式并不适用于分布式事务。那么,那些默默无闻的拓路者便总结出了以下四种解决方案:
- AT 模式:AT 模式是一种无侵入的分布式事务解决方案。用户只需关注自己的业务 sql,AT 模式会自动生成事务的二阶段提交和回滚操作。一阶段,AT 模式 会拦截业务 sql,解析 sql 语义,找到要更新的业务数据,并保存快照数据和行锁。二阶段,如果是提交,则清理快照数据;如果是回滚,则根据快照数据恢复业务数据。
- TCC 模式:侵入性强,但性能高。该模式需要用户自己根据业务场景实现 try、confirm 和 cancel 操作。此三种操作分别对应事务的开启、二阶段事务提交和二阶段事务回滚。该模式适用于对中间状态有约束的业务,如订单业务。
- Saga 模式:该模式适用于长事务,由事件驱动,各个参与者之间异步执行。如果任何一个正向操作失败,该模式会执行前面各个参与者的逆向回滚操作,回滚已提交的参与者。该模式的优点是并发度高,无长期资源锁定。
- XA 模式:XA 模式是利用事务资源对 XA 协议的支持,以 XA 协议的机制来管理分支事务。XA 模式是两阶段提交模式,通过资源管理器和事务协调者来保证事务的原子性。该模式的优点是数据的一致性较好,缺点是实现复杂度较高。
3 spring cloud
3.1 简介定义
spring cloud 是 spring 团队提供的用来帮助开发人员快速构建分布式微服务系统的一站式解决方案或规范。提供以微服务为核心的分布式系统构建标准。它并不是一个开箱即用的框架,而是一个解决方案或规范。其特性如下:
- Distributed/versioned configuration: 分布式版本配置
- Service registration and discovery: 服务注册和发现
- Routing: 路由
- Service-to-service calls: 服务调用
- Load balancing: 负载均衡
- Circuit breakers: 断路器
- Distributed messaging: 分布式消息
spring cloud 并不完全负责以上这些特性的落地或实现,而是基于这些规范整合了市面上的优秀框架,并基于微服务的格式,对这些组件进行了封装,屏蔽掉了复杂的配置或实现原理,提高了开发体验。因此,也可以将其理解为一系列框架的有序集合。
3.2 版本命名
spring cloud 集成了大量由外部公司维护的组件,故使得其较为复杂。为避免 spring cloud 本身版本与各组件的版本歧义,其在版本命名上并没有采用传统的数字版本格式,而是经历了以下两个阶段:
- 早期阶段:早期版本使用了英国伦敦地铁站名称来命名,以地铁站英文名称首字母 A - Z 的顺序来迭代,如:
- Angel
- Brixton
- Camden
- Dalston
- Edgware
- Finchley
- Greenwich
- Hoxton
- 当前阶段:当前阶段版本带上了时间前缀,如:
- 2020.0.x aka Ilford
- 2021.0.x aka Jubilee
- 2022.0.x aka Kilburn
- 2023.0.x aka Leyton
- 2024.0.x aka Moorgate
注:由于 spring cloud 依赖于 spring boot,故在使用 soring cloud 是需注意其与 spring boot 的版本对应,详细可见 spring cloud 官网 spring cloud 官网。
3.3 实现案例(netflix & alibaba)
spring cloud 规范中定义的组件的相关实现有很多,但被 spring cloud 官网认证的却只有两个系列,分别是 spring cloud netflix 系列和 spring cloud alibaba 系列。其中 spring cloud netflix 是 spring cloud 官网认证的第一代实现,2018 年 netflix 宣布停止维护其核心组件。2019 年 spring cloud 宣布 spring cloud alibaba 毕业,正式成为 spring cloud 的第二代实现。
spring cloud netflix 由美国网飞公司实现,其核心组件如下:
- eureka: 服务注册和发现
- ribbon: 负载均衡
- feign: 服务调用
- hystrix: 断路器
- zuul: 网关
spring cloud alibaba 由中国阿里巴巴公司实现,其核心组件如下:
- nacos: 服务注册和发现、配置中心
- sentinel: 限流降级
- seata: 分布式事务
- schedulex: 分布式定时任务
- rocket mq: 分布式消息
- sidecar: 异构服务
- 注:dubbo 是阿里巴巴实现的高性能 RPC 框架,其完全适配 spring cloud alibaba 生态。现已捐给 apache。
除了第三方组件外,spring cloud 自己也实现了相关优秀组件,如:
- spring cloud gateway: 服务网关
- spring cloud loadbalancer: 负载均衡器
- spring cloud openfeign: 服务调用(netflix 停止维护 feign 后,spring cloud 基于 feign 开发了 openfeign)
3.4 nacos 与 eureka 的区别
eureka | nacos | |
---|---|---|
研发公司 | Netflix(美) | 阿里巴巴(中) |
核心功能 | 服务注册与发现 | 服务注册与发现、配置中心、动态 DNS |
CAP 支持 | AP(可用性优先) | CP(强一致性)为主,支持 AP 模式 |
健康检查 | 被动(客户端心跳) | 主动(服务端通过 http、tcp 等协议检查)、被动(客户端心跳) |
服务发现协议 | http | http、rpc、dns |
持久化 | 不支持 | 支持 mysql 等持久化方式 |
客户端支持 | 主要支持 java 语言 | 支持 java、go、node.js 等 |
生态支持 | spring cloud 第一任官配(spring cloud netflix) | spring cloud 第二任官配(spring cloud alibaba) |
扩展性 | 弱(不行!) | 强(行!) |
注:关于 nacos 更详细介绍,还请移步 nacos 官网。
3.5 gateway 与 zuul 的区别
zuul | gateway | |
---|---|---|
研发公司 | Netflix | Spring |
技术背景 | 基于阻塞 IO,使用 servlet 技术,不支持长连接 | 基于非阻塞 IO,使用 webflux + netty + reactor 实现的响应式网关,支持长连接 |
路由方式 | 基于 servlet 的路由方式,较为单一 | 支持基于路径、服务、请求参数等多种路由规则来实现请求的路由和转发,更加灵活 |
过滤器 | 基于 servlet,不支持异步 | 基于 webflux,支持异步 |
性能 | 阻塞 IO(不行!) | 非阻塞 IO,性能是 zuul 的 1.6 倍(行!) |
综上所述,分布式微服务架构的组合拳可由 spring cloud 和 spring cloud alibaba 组成(截至公历 2025 年 1 月 5 日,农历甲辰年腊月初六(小寒))。
注:spring cloud alibaba 使用示例见下篇文章(我就是下篇文章《spring cloud alibaba 使用示例》,戳我!)。