文章目录
- 前言
- 负载均衡
- 反向代理
- 分布式事务
-
- 分布式事务解决方案
- [1. 两阶段提交协议](#1. 两阶段提交协议)
- [2. 三阶段提交协议](#2. 三阶段提交协议)
- [3. 补偿事务](#3. 补偿事务)
- [4. 最终一致性](#4. 最终一致性)
- 服务治理
-
- Nacos原理
- [1. 服务注册](#1. 服务注册)
-
- 1) 服务启动后注册 服务启动后注册)
- 2) 服务注册落地 服务注册落地)
- 3) 服务一致性 服务一致性)
- [2. 服务发现](#2. 服务发现)
- [3. 配置管理](#3. 配置管理)
- 缓存
- [RPC 框架 - Dubbo](#RPC 框架 - Dubbo)
-
- [1. 简介](#1. 简介)
- [2. 通信方式设计](#2. 通信方式设计)
- [3. 服务寻址](#3. 服务寻址)
-
- 1) 多样的注册中心支持 多样的注册中心支持)
- 2) 多算法负载均衡、路由和多维度流量控制 多算法负载均衡、路由和多维度流量控制)
- 3) 容错机制 容错机制)
- [4. 让业务更方便的使用](#4. 让业务更方便的使用)
- [5. 可跟踪](#5. 可跟踪)
- [6. 其他](#6. 其他)
- [Spring Cloud Gateway](#Spring Cloud Gateway)
- 分布式存储
- 微服务架构模式
-
- [1. 微服务聚合模式](#1. 微服务聚合模式)
- [2. 微服务共享模式](#2. 微服务共享模式)
- [3. 微服务代理模式](#3. 微服务代理模式)
- [4. 微服务异步消息模式](#4. 微服务异步消息模式)
- 微服务部署模式
-
- [1. 微服务多实例部署](#1. 微服务多实例部署)
- [2. 微服务容器化部署](#2. 微服务容器化部署)
- [3. 微服务Serverless部署](#3. 微服务Serverless部署)
- [4. 微服务容器编排部署](#4. 微服务容器编排部署)
前言
负载均衡
负载均衡(Load Balancing),是指将流量、或计算,负载均匀分配到多个服务器、或资源上。
比如:在处理大量的用户请求时,负载均衡器可以分配流量到多个 Web 服务器上,以保证应用的高可用性和响应速度。
如下图所示:

通过有效分配负载、提高系统的可用性、和性能,从而满足高可用、和高性能的业务需求。
比如:随着业务量的增加,可以通过增加更多的服务器来扩展系统,负载均衡器会自动将流量分配到新增加的服务器上,从而实现平滑的扩展。
以及,通过将流量或请求分配到多个服务器上,可以避免单一服务器故障导致的服务中断。
即使某些服务器出现故障,其他服务器仍可以继续处理请求。
负载均衡原理
负载均衡的基本原理:是使用一个负载均衡器(或称负载分配器),作为前端,将来自客户端的请求分配到后端的多个服务器上。

负载均衡器通常位于网络流量的入口处,扮演着流量管理的角色。
整个负载流程,大致如下:
第一:请求接收
首先,客户端发起请求,负载均衡器接收到这些请求。
第二:流量分配
其次,负载均衡器根据设定的算法、或策略,将请求分配到多个后端服务器上。
第三:请求转发
再次,负载均衡器将客户端的请求转发给选定的后端服务器。
第四:响应返回
最后,后端服务器处理请求并生成响应,负载均衡器接收响应后,将其转发回客户端。
负载均衡算法
如果想更加深入的掌握负载均衡原理,还需要掌握负载均衡的算法。
比如:当客户端到达负载均衡后,通过"负载均衡的算法",将请求分发到不同的服务器上。

1. 轮询(Round Robin)
轮询:将请求按顺序依次分配给每个服务器,每个服务器依次接收请求,形成一个循环。

比如:
服务器列表: A, B, C
请求顺序: R1, R2, R3, R4, R5
请求分配:
R1 -> A;
R2 -> B;
R3 -> C;
R4 -> A;
R5 -> B;
适用场景:
适用于服务器性能相似的场景,因为它不考虑服务器的负载、或性能,只是简单地轮流分配请求。
优点:
实现简单,易于配置。
缺点:
不考虑服务器的实际负载情况,可能导致某些服务器过载,而其他服务器空闲。
2. 加权轮询
为每个服务器分配一个"权重",权重值表示服务器处理请求的能力。

比如:服务器列表及权重: A (3), B (1), C (2)
请求顺序: R1, R2, R3, R4, R5, R6, R7, R8, R9, R10
请求分配:
R1 -> A;
R2 -> A;
R3 -> A;
R4 -> B;
R5 -> C;
适用场景:
适用于服务器性能不均等的情况,比如:一些服务器性能较高,能够处理更多请求,而其他服务器性能较低。
优点:
能够根据服务器的性能差异动态调整流量分配。
缺点:
需要准确配置权重值,权重的选择可能需要经验、或实时监控数据来优化。
3. 最少连接数
将请求分配给当前连接数最少的服务器,即选择处理请求数量最少的服务器。

比如:
服务器连接数: A (5), B (2), C (3);
请求到来顺序: R1, R2, R3, R4
请求分配:
R1 -> B (最少连接数);
R2 -> C (最少连接数);
R3 -> B (最少连接数);
R4 -> A (最少连接数);
适用场景:
适用于服务器处理请求时间长短不一的情况,能够有效分配负载,避免某些服务器过载。
优点:
动态平衡负载,适应服务器的实时负载情况。
缺点:
需要实时监控每个服务器的连接数,可能增加管理开销。
4. IP 哈希(IP Hash)
根据客户端的 IP 地址计算哈希值,将请求分配给特定的服务器。相同的客户端 IP 地址通常会被分配到同一台服务器。

比如:
IP 地址: 192.168.1.1, 192.168.1.2, 192.168.1.3;
服务器列表: A, B
IP 哈希结果:
192.168.1.1 -> A;
192.168.1.2 -> B;
192.168.1.3 -> A;
适用场景:
适用于需要会话粘性(Session Affinity)的场景,即要求同一客户端的请求始终发送到同一服务器上。
优点:
提供会话粘性,保证客户端的请求连续性。
缺点:
不均匀的流量分布可能导致负载不均衡,特别是在客户端 IP 地址分布不均的情况下。
5. 随机(Random)
随机选择一个服务器来处理请求,不考虑服务器的当前负载或性能。

比如:
服务器列表: A, B, C
请求到来顺序: R1, R2, R3, R4
请求分配(随机选择):
R1 -> C;
R2 -> A;
R3 -> B;
R4 -> A;
适用场景:
适用于负载均衡较简单的场景,或者在性能差异不大的情况下。
优点:
实现简单,容易配置。
缺点:
可能导致负载不均衡,特别是在服务器性能差异较大时。
这些负载均衡算法,可以根据不同的需求、和环境进行选择和配置,以实现最优的资源利用和系统性能。
负载均衡分类
负载均衡根据其工作在网络协议栈中的不同层次,可以分为以下几种类型:

1. 二层负载均衡
在 OSI 模型的第二层,即数据链路层进行负载均衡,所以有时候也叫:二层负载均衡(数据链路层),
二层负载均衡(数据链路层),这种负载均衡器基于 MAC 地址进行流量分配。
比如:通常用于局域网 (LAN) 环境中,主要处理 Ethernet 帧。
2. 三层负载均衡
三层负载均衡:在 OSI 模型的第三层,即网络层进行负载均衡,基于 IP 地址进行流量分配。
可以使用到:IP 负载均衡、数据中心网络中的流量管理、以及互联网流量分配。
3. 四层负载均衡
在 OSI 模型的第四层,即传输层进行负载均衡,基于 TCP 、或 UDP 端口进行流量分配。
由于操作在较低层级,通常具有较低的延迟、和较高的吞吐量。
比如:典型的Dubbo RPC就是基于TCP来进行负载均衡,原因很简单:就是我刚讲到的性能高的原因。
4. 七层负载均衡
在 OSI 模型的第七层,即应用层进行负载均衡,基于应用层数据进行流量分配。
比如:可以根据 HTTP 请求的内容、URL、主机头、Cookie ...等信息进行流量分配。
常见的七层负载均衡器有:Nginx、HAProxy...等。
可以应用到:Web 应用负载均衡、API 管理、内容分发网络 (CDN)、微服务架构...等等服务路由。
总之,二层、和三层负载均衡器通常用于低层次的流量管理,适合高性能、和简单的流量分配。
而四层、和七层负载均衡器,提供更高级的流量管理、和路由功能,适合处理复杂的应用需求、和动态环境。
正向代理
很多同学谈到很难理解反向代理,所以,在介绍反向代理之前,我们有必要一起来先了解一下:什么是正向代理?
正向代理的情况下,客户端不直接与目标服务器通信,而是通过正向代理服务器进行通信。
如下图所示:

比如:在大陆访问google,暂时无法访问,我们可以通过正向代理这种方式,访问原来无法访问的资源。
在这种情况下,你可以使用一个位于境外的代理服务器,作为正向代理来帮助你访问谷歌,因为正向代理服务器位于境外。
这个过程就是正向代理,客户端非常明确要访问的服务器地址,以及,正向代理还隐藏了客户端的真实IP地址,还保护了客户端的隐私、和安全。
一句话总结正向代理:客户端不直接与目标服务器通信,而是通过正向代理服务器进行通信,这就是正向代理。
反向代理
反向代理,从字面上就很清楚,反向代理和正向代理在概念上是相反的。
正向代理:客户端知道代理服务器的存在,而服务器不知道客户端的真实身份。
而反向代理:客户端对代理是无感知的,因为客户端不需要任何配置就可以访问。
来看个示意图:

我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择,目标服务器获取数据后,再返回给客户端。
此时反向代理服务器、和目标服务器,对外就是一个服务器,暴露的是反向代理服务器地址,并且,隐藏了真实服务器IP地址。
反向代理服务,主要用于:负载均衡、缓存加速等场景。
例如:在Web服务器架构中,使用反向代理(Nginx),来将请求分发到多个后端服务器,实现负载均衡和高可用性。
Nginx
了解完反向代理后,就很容易掌握Nginx反向代理了。
原因很简单,因为Nginx反向代理,只不过是实现反向代理的一种方式而已。
Nginx配置如下:
conf
server {
配置参数,如下图所示:

-
location: # server 块可以包含多个 location 块,location 指令用于匹配 uri;
-
proxy_pass: 定义后端服务器的地址;
-
upstream: 定义后端服务器的集群,可以包含多个服务器。
Nginx反向代理原理
整体工作流程,如下:
-
首先,接收请求: Nginx接收来自客户端的HTTP请求。
-
其次,选择后端服务器: 根据配置的规则,Nginx选择一个或多个后端服务器来处理请求。
-
然后,转发请求: Nginx将请求转发给选定的后端服务器。
-
然后,接收响应: 后端服务器处理请求并生成响应,然后将响应发送回Nginx。
-
最后,返回响应: Nginx将后端服务器的响应发送回客户端。
总之,Nginx反向代理是一个强大且灵活的工具,可以帮助构建高性能、高可用性和安全性的大型应用程序架构。
分布式事务
分布式事务,是指涉及多个参与者,通常是不同的计算机节点或服务的事务操作,因此需要跨多个节点执行事务操作。
如下图所示:

分布式事务需要确保所有相关操作要么全部成功执行,要么全部回滚,以维护数据的一致性和可靠性。
分布式事务解决方案
常见的分布式事务解决方案,主要包含有以下四种:
1. 两阶段提交协议
两阶段提交协议,Two-Phase Commit,简称是2PC,该协议包括:准备和提交两个阶段。
如下图所示:

1.准备阶段
协调者向所有参与者发送准备请求,参与者执行事务准备,并向协调者发送准备就绪的通知。
2.提交阶段
如果所有参与者都准备就绪,则协调者向所有参与者发送提交请求,参与者执行事务提交。
如果所有参与者都成功提交了事务,则事务成功完成。
否则,如果任何一个参与者失败或者无法提交,则所有参与者都会被要求回滚(Rollback)事务,以保持一致性。
2PC的优点是简单易懂,并且在理想情况下能够保证分布式系统中事务的原子性和一致性。
两阶段有如下几个缺点:
1.阻塞问题
在2PC的准备阶段,协调者需要等待所有参与者的响应,这可能会导致整个系统的阻塞。
2.单点故障
在2PC中,协调者是一个单点,它负责协调所有参与者的操作。
如果协调者发生故障,那么整个事务可能会无法完成,即使参与者的大部分已经准备好了,这种单点故障会影响系统的可用性和可靠性。
3.数据不一致性
2PC无法处理所有故障情况,例如:协调者和参与者之间的网络分区或者通信失败。
在这种情况下,可能会出现数据不一致性,一些参与者已经提交了事务,而另一些参与者却未收到提交指令,导致系统状态混乱。
2. 三阶段提交协议
三阶段提交协议,Three-phase commit, 简称是3PC,3PC是2PC的改进版。
如下图所示:

3PC的主要思想是引入一个【预提交阶段】,以减轻2PC中的阻塞问题,同时保持原子性和一致性。
3PC,主要分为三个阶段:
1.预提交阶段
协调者询问参与者是否可以提交事务,并等待它们的响应,如果所有参与者都同意,则进入下一阶段。
2.提交阶段
协调者向所有参与者发送提交请求,要求它们提交事务,如果任何参与者无法提交,则执行回滚。
3.确认阶段
协调者向所有参与者发送确认消息,告知它们事务已经提交,这一阶段用于解决2PC中的阻塞问题。
3PC相较于2PC的优点是在第一阶段引入了一个"询问"阶段,避免了2PC的直接准备阶段可能出现的长时间阻塞问题。
两阶段与三阶段对比,如下图所示:

3. 补偿事务
TCC(Try-Confirm-Cancel)是一种补偿性事务处理模式,用于实现分布式系统中的一致性操作。
如下图所示:

TCC模式通过三个阶段的操作来确保事务的一致性:尝试(Try)、确认(Confirm)和取消(Cancel)。
1.尝试阶段(Try)
在尝试阶段,系统会尝试执行事务操作的所有必要检查和准备工作,以确保事务能够成功执行。
这包括检查资源的可用性、锁定所需资源等,如果所有的检查都通过,系统会记录下所有的尝试操作,但并不会实际执行事务。
2.确认阶段(Confirm)
在确认阶段,系统会执行事务操作,并且确认之前所做的尝试操作。
如果事务操作成功执行,系统将确认并提交事务,在这个阶段,系统会持久化事务的结果,确保事务的最终执行。
3.取消阶段(Cancel)
如果在尝试阶段或者确认阶段发生了错误或者异常情况,系统将进入取消阶段。
在这个阶段,系统会执行逆向操作,取消之前尝试阶段所做的操作,这样可以确保系统的状态回滚到事务开始之前的状态,以维持数据的一致性。
TCC模式允许开发人员在每个阶段都定义自己的业务逻辑和补偿操作,以适应不同的业务需求。
但是,TCC模式要求开发人员在每个阶段都显式定义业务逻辑和补偿操作,这增加了系统的复杂性和开发成本,需要设计和维护每个阶段的逻辑,并确保它们之间的一致性。
4. 最终一致性
最终一致性是分布式系统中的一种一致性模型,它允许数据副本在一段时间内的状态之间存在不一致,但最终将会达到一致的状态。
如下图所示:

在最终一致性模型中,节点之间的数据同步通常是通过消息传递来实现的。
当一个节点的数据发生变化时,它会通过异步方式将消息发送给其他节点,由于消息传递是异步的,因此节点之间的数据同步可能会有一定的延迟。
因此,最终一致性模型允许节点之间的数据副本,在一段时间内存在不一致,但最终会收敛到一致的状态。
服务治理
Nacos是微服务的核心组件,全称是Dynamic Naming and Configuration Service,是阿里巴巴开发的一款动态服务发现、配置管理、和服务管理平台。主要用于微服务架构中的服务注册、发现、配置管理等核心功能。

Nacos原理
Nacos架构,如下图所示:

Nacos 的核心原理,主要围绕 服务发现、服务注册、配置管理、健康检查 等功能展开。
1. 服务注册
服务注册,是指微服务启动后将自己的实例信息(如:IP 地址、端口号、服务名等)注册到 Nacos。
如下图所示:

工作流程,如下:
1) 服务启动后注册
当一个微服务实例启动后,它会主动向服务注册中心,发送一个注册请求.
携带服务的元数据(如:服务名、实例ID、IP地址、端口、健康检查URL。。。等)。
服务注册中心接收到该请求后,会将该服务实例的信息存储到自己的注册表中。
2) 服务注册落地
Nacos 服务器接收到注册请求后,将该服务实例的信息存储。
比如:Nacos 服务器接收到注册请求后,将该服务实例的信息存储到 注册表 中(保存在内存、或持久化存储中)。
3) 服务一致性
Nacos 通过 Raft 一致性协议,保证服务实例数据在集群中保持一致,确保数据的可靠性、和一致性。
Raft 通过选举一个 Leader 节点,来管理注册表的写入操作,Leader 将数据写入后,同步到其他 Follower 节点,保证数据一致。
2. 服务发现
服务发现,是指服务消费者在调用服务时,通过 Nacos 获取到服务提供者的网络地址信息。
服务消费者在需要调用某个服务时,会通过服务注册中心查找目标服务的位置信息。
如下图所示:

比如:实例的 IP 地址、和端口,获取一个、或多个可用的服务实例。
消费者可以直接选择一个实例进行调用,或者使用负载均衡策略选择最合适的实例。
Nacos 提供了两种服务发现模式:
主动拉取模式:客户端通过 Nacos 的 API ,主动查询某个服务的实例列表;
被动推送模式:当注册的服务实例发生变化时,Nacos 会通过长连接、或推送的方式,将更新通知客户端。
3. 配置管理
Nacos 配置管理的核心:是实现对配置的集中管理、和动态更新。
避免了配置,散布在多个微服务实例中带来的维护复杂性。
用户将配置以 Key-Value 形式存储到 Nacos 中,Nacos 服务器会将配置保存到持久化存储。
为了实现配置的动态更新,Nacos 采用了长轮询机制,客户端会定期(默认 30 秒)向 Nacos 服务端发起请求,询问配置是否有变更。
如下图所示:

如果配置发生变更,Nacos 服务端会将最新的配置推送给客户端。
客户端在收到新的配置后,可以根据需要进行处理,比如:动态刷新、更新内存中的配置。
缓存
实现高并发的核心
内存存储
Redis 是一个内存数据存储系统,所有的数据都存在内存中,这使得数据读写速度非常快。
内存访问比磁盘访问要快得多,这使得 Redis 在处理大量请求时能保持极高的性能。
RAM 的读写速度远远快于磁盘,无论是机械硬盘(HDD)还是固态硬盘(SSD)。

内存的带宽和延迟通常比磁盘小几个数量级,对于数据库来说,内存可以在微秒级别完成读取操作,而磁盘操作通常需要毫秒甚至更长时间。
IO多路复用技术
Redis 通过 I/O 多路复用技术,尤其是 epoll,实现了高效的事件驱动模型。

主要的 I/O 多路复用技术
- select
最早的 I/O 多路复用机制,支持同时监视多个文件描述符(FD),当某个文件描述符变为可读、可写或发生异常时,select 返回通知。
- poll
类似于 select,但支持更多的文件描述符,避免了 select 的文件描述符数量限制。
- epoll
Linux 系统上的高效多路复用机制,解决了 select 和 poll 在大规模并发时的性能瓶颈,特别适用于处理数以千计的客户端连接。
epoll 是事件驱动的,在检测到事件时才通知应用程序处理,大大提高了性能。
epoll 的效率远高于 select 、和 poll,使得 Redis 具有极高的性能。
这种模型使得 Redis 可以同时处理大量的客户端连接,并对每个连接的事件进行及时的响应,从而保证了 Redis 的高性能和高并发性。
数据结构
Redis 支持高效的内存数据结构,如:字符串、哈希、列表、集合、排序集合等。

这些数据结构被高度优化,以便于快速的存储和检索。
内存中的数据结构是基于简单且高效的算法设计的,能够支持快速插入、删除、查找、更新等操作。
集群模式
Redis 集群通过分片的方式将数据分布到多个节点上,实现水平扩展,提高系统的处理能力。

Redis 集群提供了高可用性,即使某个节点发生故障,也不会影响整个系统的可用性。
对于高并发场景,建议采用 Redis 集群部署。
RPC 框架 - Dubbo
阿里的Dubbo是大家使用比较多的RPC框架,阿里面试也会经常问到底层的实现细节,下面详解如何设计实现Dubbo。
1. 简介
单体应用时代只有内外网通信,并没有服务间通信的诉求。
随着业务的快速发展,业务越来越多、子系统也越来越多时。比如:淘宝的交易系统、商品系统、用户系统、评价系统...上百个系统的出现。

应用系统一旦涉及到拆分部署,问题就来了,急需一种高效的应用程序间的通讯手段来完成这种需求,这就会涉及到分布式远程调用。
RPC ,Remote Procedure Call ,字面意思是远程过程调用,主要是解决服务间连接及数据交互,但除了通信和数据交互,为适应分布式架构/微服务架构的设计。
一个好的系统设计,通常是完整、系统、可扩展、可容错、高性能、支持高并发、可跟踪、有良好的设计模式等等,Dubbo框架的设计需要解决什么问题?
2. 通信方式设计
通信的底层是TCP/IP,在Java中网络传输通常使用Netty 或 Mina 的多路复用模型作为网络通信的底层。
- 多传输协议支持
为什么要支持多种传输协议呢?在业务中,通常会遇到各种问题,比如:
-
跨网络、机房问题
-
跨语言问题
-
长连接还是短连接
-
传输安全
-
传输性能
使用Http协议,虽然灵活便于管理、可以跨语言,但是明文、性能很差。通常适用于较低并发、异构系统对接、对外网关等。
使用Dubbo 传输协议,性能高、长连接,但目前跨语言做的还不够,单条大文件/数据传输可能会形成网络瓶颈。
Rmi ,性能较差,短连接,但对于单次大数据量传输却比较好,其他的还有Websocket 、Https、Thrift TTransport等,传输协议各有优缺点,所以支持多传输协议是有必要的。
- 多数据压缩/序列化支持
为什么要支持多序列化支持,主要考虑两个方面
-
跨语言/异构平台间交互
-
性能方面考虑
这个其实跟传输协议是搭配的,比如RMI 通常都是使用了标准的二进制序列化
目前有Protobuff、Dubbo 序列化、Hessian 、Java原生、Soap文本序列化、Http的表单序列化、Json、Thrift的TCompactProtocol等,同样各有优缺点,需要设计成可扩展的方式。
3. 服务寻址
如何找到服务并且实现资源合理
服务消费者如何知道服务提供者,并且知道当前是否存活,是设计 RPC 框架需要考虑的第二大问题。
1) 多样的注册中心支持

不同的业务系统,对于服务间一致性要求并不同,这里有一个CAP权衡问题。
另外还要考虑是否推送提供者的变动、注册中心自身的安全问题、跨语言平台等因素。
比如:
-
zookeeper,支持强一致并能通过Wacher机制主动进行通知,但可用性并不能完全保证 -
Consul,通过Http方式满足服务发现,没有语言限制,但通知实时性比ZK Wacher略差
所以注册中心也需要做成插件化的可扩展方式。
2) 多算法负载均衡、路由和多维度流量控制
负载均衡目的是为了最优使用同一服务间的资源,具体到设计中,需要考虑硬件状况、服务的负载情况等。
算法主要有随机、轮询、活跃情况、一致性Hash等。
在生产环境中能通过界面化的方式提供动态的更改权重、路由等规则,实现服务动态权重、熔断、限流、灰度、多版本等功能。
3) 容错机制
考虑容错机制是系统完整性的一部分,failover、failfast、failback、failsafe 、forking、Broadcast 等,通常和负载均衡搭配。
4. 让业务更方便的使用
支持普通配置的同时,支持集成到Spring等主流框架使用。
配置的方式也有很多种,比如支持XML、注解、YAML、Properties、Json配置等。
5. 可跟踪
可以进行依赖分析,数据的调用统计,并能图形、数据化将其显示出来。
可跟踪需要解决这几个问题:
-
服务调用链路或依赖关系
-
调用次数及时间,提供容量/机器预算基准数据
-
预警
实现上可以兼容现有成型的APM链路跟踪,也是设计的考虑因素之一。
6. 其他
从架构的角度要考虑到设计模式的使用,比如常用的责任链、代理模式等。
容器化,Kubernetes 支持等

正如前面说的,RPC 框架相当于电网基建,是分布式系统的基础,如果不具备可靠、高性能、高并发、使用简易等特点,就很难满足日益增长的服务治理的需要。
实现RPC调用可能比较简单,但实现Rpc框架不仅需要深厚技术功底,也需要提供接地气、灵活的使用方式。
Spring Cloud Gateway
采用响应式非阻塞架构
Gateway 基于 Reactor 与 Netty,能够以较少线程处理大量并发连接。

// 反例:阻塞等待 String result = webClient.get() .uri(authUrl) .retrieve() .bodyToMono(String.class) .block();
基于 Reactor Netty(事件驱动 + NIO 多路复用)。
少量 EventLoop / Worker 线程(通常 = CPU 核数或核数 × 1.5~2)就能管理成千上万连接。
请求进来后注册回调,线程立刻释放去处理其他请求,I/O 等待不阻塞线程。
它的优势不是"线程特别多",而是网络等待不必对应一个被阻塞的业务线程。
实施限流与过载保护
面对百万级洪峰流量,网关的首要任务是"保命"。
如果所有请求无限制地涌入下游微服务,整个微服务集群会瞬间被打垮。
限流:官方 RequestRateLimiter 基于 Redis + Lua 脚本实现令牌桶算法(replenishRate 填充速率 + burstCapacity 突发容量)。
支持按 IP、用户、路径等 Key 限流,集群级原子精确。也可接 Sentinel / Resilience4j。

熔断:集成 Resilience4j 或 Sentinel,失败率/慢调用超阈值快速失败,并支持 fallbackUri 降级。
配合隔离舱、降级开关(Nacos 动态配置),保护核心链路。
建立可观测与弹性扩容机制
水平扩展:单机有上限,Gateway 集群 + 前置负载均衡(Nginx/SLB/K8s Ingress)分摊流量。

持续监控请求量、延迟、错误率、连接池状态和 JVM 指标,借助压测发现瓶颈,并依据流量动态扩缩容。
同时,部署多个网关实例并配合负载均衡,减少单点故障风险。
做好连接与资源管理
合理配置连接池、超时、队列和线程数,避免连接过多或请求无限等待。
对下游服务设置连接超时、响应超时及并发上限,使资源使用保持在可控范围内。
分布式存储
分布式存储技术是大型架构的基石
分布式文件存储
随着互联网、大数据、云计算和人工智能等技术的发展,数据量呈爆炸式增长。
传统的文件存储方式,难以满足日益增长的存储需求,它们通常面临扩展性差、单点故障、性能瓶颈等问题。

分布式文件存储应运而生,它通过将文件数据分割成小块,并存储在集群中的多台机器上。 从而实现了海量数据的存储,目前已成为构建可扩展、可靠的云计算平台、和大数据分析系统的基石。
1) HDFS
HDFS是Hadoop生态系统的核心组件之一,专为大数据存储而设计。
它采用Master-Slave架构,主要由以下几部分组成:

NameNode(主节点)
负责管理元数据(如文件目录结构、块位置、权限等),是整个系统的"调度大脑"。
DataNode(数据节点)
负责真正的数据存储,每个文件被切分为多个数据块(Block),分布在多个 DataNode 上。
客户端(Client)
通过 NameNode 获取元数据信息后,直接与 DataNode 通信,进行数据读写。
HDFS主要用于存储海量大文件,特别是那些需要进行大数据分析的文件。
作为Hadoop的存储层,支持MapReduce、Spark、Hive等大数据处理框架。
2) CephFS
CephFS 是 Ceph 提供的 POSIX 兼容的分布式文件系统,其架构基于 Ceph 的统一存储平台构建。
整体架构,如下图所示:

主要包含,如下组件:
RADOS(底层对象存储)
Ceph的底层存储引擎,负责所有数据的存储、复制、故障恢复和一致性保证。
所有实际的数据、和元数据块都存储在 RADOS 对象中,由 OSD 守护进程负责管理
OSD
Ceph集群中存储数据的基本单元,每个OSD管理一个本地磁盘上的对象集合。
OSD负责数据读写、副本管理、数据恢复等。
MDS(元数据服务器)
存储和管理CephFS的元数据(文件和目录结构、权限等)。
MDS不存储实际的文件数据,只管理文件的元信息。
与HDFS不同,CephFS更强调通用性,能更好地支持各种大小的文件和更频繁的修改操作。
3) GFS
GFS 是 Google 为大规模数据处理而设计的分布式文件系统,其架构影响了 Hadoop HDFS 的设计。
整体架构,如下图所示:

Master(主节点)
存储元数据,如文件目录、块映射关系。
ChunkServer(块服务器)
实际存储数据块(Chunk),每个块默认大小为 64MB,并有多个副本。
Client
与 Master 通信获取元信息,再与 ChunkServer 直接通信处理数据。
GFS设计之初的目标是支持Google内部的大规模、高吞吐量、追加写入的批处理应用。
比如:Web爬虫、索引构建等,它为大数据量、低成本、高可靠性的存储提供了解决方案。
4) TFS
TFS是阿里巴巴,针对其电商业务特点(特别是图片、音视频等海量小文件存储和访问),而开发的分布式文件系统。
TFS也采用了Master-Slave架构,并在此基础上进行了优化:

比如:淘宝图片,商品图片、用户头像...等等,被广泛部署在阿里系的多个核心业务中。
TFS的核心作用是:解决海量小文件的存储、和高并发访问问题。
微服务架构模式
微服务是大型架构的基石
1. 微服务聚合模式
微服务聚合设计模式,解决了如何从多个微服务中聚合数据,以便客户端可以获得所需的完整信息,而不需要多次请求不同的服务。
此类模式主要用于简化客户端的操作,减少与多个微服务交互的复杂性。
如下图所示:

通过构建一个聚合服务(又称聚合层或聚合微服务),将多个微服务的响应数据进行聚合,形成一个统一的结果返回给客户端。
聚合服务,通过调用多个微服务的 API,收集它们的响应并进行整合。
优点:
简化客户端请求:客户端只需调用聚合服务,不需要直接与多个微服务交互。
减少服务间依赖:聚合服务可以减轻微服务之间的耦合度,服务间可以独立变化。
缺点:
聚合服务可能成为性能瓶颈,需特别关注聚合服务的可扩展性。
如果聚合的服务很多,可能需要额外的处理来确保高效聚合。
2. 微服务共享模式
微服务提倡的是:每个服务拥有自己的独立数据库(比如:数据库独立性原则),以确保服务之间的高内聚性、和低耦合性。
然而,在某些情况下,由于业务需求或技术限制,多个微服务可能需要共享数据。
如下图所示:

实际上在微服务架构的初期阶段,很多企业可能会采用 共享数据库 模式,来简化系统的开发和维护,尤其是在微服务迁移的过渡阶段。
这样做虽然简化了架构,但却违反了微服务的原则,因为它导致了微服务之间的紧密耦合。
因此,"共享数据库"模式通常被视为"过渡性"或"反模式",不是长期推荐的设计。
3. 微服务代理模式
微服务代理是一种中间层,用于处理服务之间的通信。
如下图所示:

在这种模式下,代理服务充当了其他微服务的代理,接收客户端的请求并将其转发给后端服务进行处理。
在 Sidecar 代理模式 中,Sidecar 是与每个微服务实例配对部署的。

每个微服务实例旁边都有一个独立的代理进程,这些代理共同组成一个统一的服务网格。
代理负责捕获并管理服务的入站和出站流量。代理通常会与服务网格的 控制平面 交互,获取流量路由、负载均衡、访问策略等配置。
优点:
解耦:客户端和微服务之间的交互通过代理服务来处理。
统一入口:所有请求都经过代理,易于管理、监控和控制。
缺点:代理服务需要额外的资源来处理请求,可能成为性能瓶颈。
4. 微服务异步消息模式
异步消息设计模式,在微服务架构中非常重要,它允许微服务通过消息队列、事件流等方式进行松散耦合的通信。
如下图所示:

微服务通过发布事件来通知其他服务发生了某个状态变化。事件通常是业务变化或数据变化的通知,例如:订单创建、支付成功...等。
优点:
服务解耦:服务之间不需要直接调用,只有事件通知机制。
提高吞吐量:通过异步处理,减少了服务的同步依赖。
缺点:事件的顺序和一致性需要额外考虑,容易出现"事件丢失"或"消息重复消费"的问题。
微服务部署模式
微服务部署是微服务非常重要的环节
1. 微服务多实例部署
微服务多实例部署:是微服务架构中最基础、最常见的部署模式,通过为每个微服务部署多个运行实例。
如下图所示:

比如:在一台服务器上,部署了用户服务 (User Service) 的两个实例。
实例1:
yaml
1. server:
2. port:8081
3. spring:
4. application:
5. name: user-service
实例2:
yaml
1. server:
2. port:8082
3. spring:
4. application:
5. name: user-service
每个微服务实例必须监听不同的网络端口,以避免端口冲突。
然而,需要注意单台服务器的资源限制、和潜在的单点故障风险。
比如:单台服务器的 CPU、内存和网络资源是有限的,运行过多的实例可能会导致资源竞争,反而降低性能。
对于生产环境中的关键微服务,建议考虑跨多台服务器的分布式部署。
2. 微服务容器化部署
微服务容器化部署:是一种将每个微服务、及其所有依赖项,打包到独立容器中的部署方法。
如下图所示:

可以使用Docker(最流行的容器化平台),用于构建、打包、分发和运行容器。
Docker 将微服务及其运行环境(JDK、依赖库等),打包成镜像。
bash
1. docker build -t user-service:1.0.
无论部署在哪台服务器上,都能保持行为一致。
bash
1. docker run -d -p 8080:8080--name user-service user-service:1.0
大大减少了"开发能跑、测试能跑、线上跑不了"的问题。
真正做到,一次构建,到处运行(Build once, run anywhere)。
3. 微服务Serverless部署
微服务 Serverless 部署:是一种将服务部署、和运行责任交给云平台的现代架构方式。
微服务 Serverless 部署带来了与传统容器化部署不同的价值,它进一步抽象了基础设施管理,让开发者更专注于业务逻辑。

Serverless 平台,比如: AWS Lambda...等等,负责底层的基础设施管理。
开发者无需关心这些运维细节,可以将更多精力投入到业务代码的编写。
Serverless 部署,通常根据实际的请求量自动弹性伸缩,无需预先配置或管理实例。
只为实际执行的计算资源付费,闲置时不产生费用,可以显著降低成本,尤其对于流量波动较大的服务。
4. 微服务容器编排部署
除此之外,还可以结合容器化、与自动化编排,比如:K8S等来部署。
如下图所示:

bash
1. 用户请求
2. │
3. ┌─▼──────┐
4. │Ingress│⇽⇽Nginx入口控制器
5. └─┬──────┘
6. │
7. ┌─▼────────────┐
8. │Service(ClusterIP)│⇽⇽微服务的内部服务发现
9. └─┬────────────┘
10. │
11. ┌─▼────────────┐
12. │Pod(多个副本)│⇽⇽每个Pod运行1个微服务实例
13. └──────────────┘
Kubernetes 可以自动化微服务的部署、更新和回滚过程,大大简化了发布流程。
Kubernetes 可以在各种环境中部署,包括公有云、私有云和混合云。
Kubernetes 解决了大规模微服务部署、和管理中的诸多挑战。
本文的引用仅限自我学习如有侵权,请联系作者删除。
参考知识
Spring Cloud Gateway如何抗住亿级流量请求?