GQ SpringCloud

什么是配置中心?有哪些常见的配置中心?

每⼀个服务最终都有⼤量的配置,并且每个服务都可能部署在多台机器上。我们经常需要变更配置,我们可以让每个服务在配置中⼼获取⾃⼰的配置。
配置中⼼⽤来集中管理微服务的配置信息,常用的有nacos和zookeeper

img

为什么需要服务注册发现?

  • A 服务调⽤ B 服务,A 服务并不知道 B 服务当前在哪⼏台服务器有,哪些正常的,哪些服务已经下线。解决这个问题可以引⼊注册中⼼
  • 注册中⼼中在远程调用之前,需要发现对方在哪,注册中心会根据服务注册的清单给发起者返回信息告诉它对方在哪个服务器中
  • 经过了服务发现后,发起者知道了需求的业务在哪些服务器中,就可以利用负载均衡的思想,把请求分摊给不同的服务器中
  • 如果某些服务下线,我们其他⼈可以实时的感知到其他服务的状态,从⽽避免调⽤不可⽤的服务
    img

Spring Cloud 的优缺点有哪些?

优点:集成度高,功能全面,生态丰富,扩展性强
缺点:学习成本高,组件迭代快版本多,性能开销大,管理复杂

Spring Boot 和 Spring Cloud 之间的区别?

springboot 是基础,springcloud 将多个 springboot 服务构建为微服务架构

Spring Cloud 由什么组成?

1.服务发现和注册:Nacos
2.负载均衡:LoadBalance
3.服务容错:Sentinel
4.远程调用:OpenFeign
5.服务网关:GateWay
6.事务处理:Seata

你是怎么理解微服务的?

微服务是一种架构风格,核心思想是把一个大型的单体应用,按照“单一职责原则”拆分成一组独立、自治的小服务。每个服务只负责一件事,可以自由选择技术栈,拥有独立的数据库,支持独立部署、独立扩缩容。

服务之间通过轻量级通信协议(比如 HTTP、RPC)交互,从而让整个系统更灵活、可维护、可扩展。
好处是提升敏捷性、降低耦合,但同时也会带来分布式架构的复杂性,比如服务治理、链路追踪、容错、部署运维等问题,需要配套的 DevOps 和自动化基础设施。

一句话总结:
微服务就是“拒绝大型单体应用,把业务拆成松耦合的小服务,各自独立迭代和部署”。

什么情况下需要使用分布式事务,有哪些方案?

当一次业务操作跨多个微服务/多个数据库/多种资源(如 DB + MQ、DB 分库分表)且需要保证跨资源的一致性时,需要分布式事务。典型场景:

  • 下单同时扣库存、扣余额(订单服务 + 库存服务 + 账户服务)
  • 电商拆库(分库分表)后的多库写一致
  • DB 与 MQ 之间要保证“消息发送与本地写库”一致

你们的服务是怎么做日志收集的?

  • 我当前项目的的做法很简单:利用Logback,既打控制台,也打本地文件。每个服务把运行日志按固定格式写到本机的 logs 目录,按“日期+大小”自动切分,保留一段时间。出问题就直接看这些日志,定位很快。
  • 需要集中查看时,也不用改代码,只要在服务器上加个日志收集器Logstash、,把这些文件统一送到一个搜索平台(比如 ES),再用一个网页(比如 Kibana)来搜、画图、做告警就行。(也就是ELK)
  • 一句话流程:服务写文件 → 收集器把文件送到搜索库 → 网页上一搜就能看到所有服务的日志。

这样做的好处是:实现简单、出问题好排查;要升级成“像 ELK 那样的集中日志系统”也很容易,基本是平台侧加收集与展示,不用动业务代码。

什么是 Seata?

Seata一款分布式事务解决方案。主要用于解决微服务架构下的分布式事务问题。
在 Seata 中有三个很重要的角色:事务协调者(TC)、事务管理者(TM)以及事务的作业管理器(RM)。

  • TC: 相当于项目经理,TC 去来感知全局事务和分支事务的状态,基于它们的状态,然后驱动谁来提交,谁来回滚,TC 是一个中间件,需要下载 TC 服务器启动起来
  • TM:负责发起任务,开启全局事务,全局事务要调用每一个微服务,做自己的分支事情
  • RM:每一个微服务里面去控制事务的在 Seata 中称为 RM 资源管理器,只管理自己的资源,它的作用就是处理好它的分支事务,它分支事务的提交回滚都是 RM 来做,RM 也要跟 TC 及时通信,去来及时的报告它的事务状态,方便 TC 进行总体管控

Seata 支持哪些模式的分布式事务?

Seata AT 模式(默认)

img

Seata XA 模式

img
XA 模式也是一种二阶提交协议,不同的是第一阶段它并不会给本地数据库真正的提交数据,它会阻塞住这个事务请求,只有在第二阶段确认要提交以后才会真正去提交

img
补充:AT->XA (不推荐)

img

Seata TCC 模式

img

img
第一阶段叫准备,我该给数据库里面存什么或删什么,第一阶段给它执行完

第二阶段提交或回滚,大家都成了提交,有一个败了回滚 这里的 prepare,commit,rollback 需要程序员去定义每一个阶段的实现代码

img
TCC 模式适合于一些夹杂了非数据库的事务代码。需要我们全程手写,TC 服务器仅帮我们协调调用每一个阶段

Seata Saga 模式

img

img

小结

Seata 目前支持四种事务模式,分别是 AT、TCC、Saga、XA,不同模式适合不同场景

1️ AT 模式
最常用的一种模式,通过代理数据库操作实现分布式事务。
它在业务操作前后自动生成回滚日志,提交时直接提交本地事务,回滚时通过日志恢复数据。

  • 优点: 无侵入、使用简单,只适合关系型数据库。
  • 缺点: 不能同时操作非关系型数据,比如 Redis。

2️ TCC 模式
三阶段提交模型(Try、Confirm、Cancel),开发者自己实现每个步骤的逻辑。

  • 优点: 可跨多种资源(如 Redis、ES 等),性能高。
  • 缺点: 代码侵入性大,需要自己写补偿逻辑。
    3️ Saga 模式
    适合“长事务”场景,比如涉及外部系统(如支付、接口调用)。
    把全局事务拆分成多个小事务,每个小事务都有补偿操作,按顺序执行或回滚。
  • 优点: 适合异步、长流程;
  • 缺点: 一致性是最终一致,不是强一致。

4️ XA 模式
基于两阶段提交协议(2PC)的强一致模型。

  • 优点: 一致性最强;
  • 缺点: 性能相对较差,适合银行或高一致性业务场景。

一句话总结

Seata 有四种模式:AT 最常用、TCC 性能高、Saga 适合长事务、XA 保证强一致性

了解 Seata 的实现原理吗?

img
三个核心组件:事务协调者TC,事务管理器TM,资源管理器RM

TC

TC: 相当于项目经理,TC 去来感知全局事务和分支事务的状态,基于它们的状态,然后驱动谁来提交,谁来回滚,TC 是一个中间件,需要下载 TC 服务器启动起来

  • 管理所有事务(全局 + 分支)状态;
  • 决定:谁提交、谁回滚;
  • 是一个中间件,需要独立部署;
  • 所有 RM、TM 都要和 TC 通信。

TM

TM:负责发起任务,开启全局事务,全局事务要调用每一个微服务,做自己的分支事情

是全局事务的发起者;
一般存在于业务服务(如:下单服务、支付服务)中;
负责:

  • 开启一个 全局事务
  • 调用多个子服务(每个服务执行自己的 “分支事务”);
  • 最终由 TC 统一控制提交或回滚。

RM

RM:每一个微服务里面去控制事务的在 Seata 中称为 RM 资源管理器,只管理自己的资源,它的作用就是处理好它的分支事务,它分支事务的提交回滚都是 RM 来做,RM 也要跟 TC 及时通信,去来及时的报告它的事务状态,方便 TC 进行总体管控

每个微服务里负责自己的本地数据库事务
通过 undo_log 实现回滚(哪怕之前已经提交,也能改回来)。

简述一下流程:

整个工作流程就是:首先全局事务如果要开始,业务的入口会开启一个 global transaction(全局事务),全局事务的开启也要告诉 TC,TC 知道我们要开始做一个全局事务了,接下来我们每调用的一个远程微服务它们就是一个分支事务,如果它们的事务开始,它们要注册自己的分支事务给 TC,那么 TC 也知道我们当前全局事务的当前状态正在做某一个分支事务,而且这个分支事务的状态也要汇报给 TC(分支事务是提交了还是回滚了),每一个微服务都一样,那这样的话如果某一个环节出现问题例如 accout,TC 就会要求那个出问题的微服务 accout 对他的事务进行回滚,而且由于 TC 知道 accout 出了问题,而其他微服务可能不知道,它们可能已经提交了,但就算你提交了,TC 会要求你们把提交的数据再改回去,已提交的事务怎么改回去,它是基于一个 undo_log 机制,Seata 的工作原理就是这样的

小结

步骤 1:开始全局事务(TM 发起)

  • 比如业务入口是 Business 服务(下单);

  • TM 开启一个 Global Transaction(全局事务);

  • 并通知 TC:我们开始做全局事务了。
    步骤 2:调用其他微服务(产生分支事务)

  • TM 在事务中调用了 Storage、Order、Account 等服务;

  • 每个服务的 RM 会:

    • 注册自己的分支事务到 TC;
    • 执行自己的本地事务(如扣库存);
    • 上报执行状态(成功 / 失败)给 TC。
      步骤 3:TC 做决策(统一协调)
  • 如果所有分支都成功 → TC 通知所有 RM 执行 提交;

  • 如果有一个服务失败(比如 Account 余额不足) → TC 通知所有服务 回滚。
    步骤 4:RM 根据命令执行提交 / 回滚

  • 即使某个服务已经提交了事务,只要 TC 要求回滚;

  • RM 会用 undo_log 把已提交的数据 “改回去”;

  • 保证全局事务的最终一致性。

总结一句话:

Seata 就像一个指挥系统,TM 发起事务,RM 执行本地操作,TC 统一管理事务命运(提交或回滚),通过 undo_log 实现真正的分布式事务一致性。

Seata 的事务回滚是怎么实现的?

AT 模式下的二阶提交协议

img
二阶事务的第一阶段就是每一个分支事务先去自己的数据库本地提交,但是要提交两个东西:第一个你业务修改后的数据和第二个 undo_log 回滚日志,这样 Seata(TC 服务器)就知道谁在第一阶段成了,谁在第一阶段败了

第二阶段,如果每个分支事务都成了,TC 会通知每个微服务,告知它们可以提交本次分支事务,而每一个微服务只需要把自己的 undo_log 日志一删就可以了。如果某个事务失败了,Seata 就会通知每一个已经成功本地提交的微服务去回滚,一旦每一个微服务收到了 Seata 服务器的回滚通知该怎么办,那么每一个微服务就会开启一个回滚任务,这个任务也是一个事务,主要做这么几件事:第一件步,找到 undo_log 记录(根据全局事务 id 和分支事务 id)我的 undo_log 记录我的前镜像和后镜像。第二步,做一个数据校验,后镜像和当前数据进行一个对比,如果一致就可以放心大胆的回滚,如果不一致,说明外部有一些其他渠道修改了,需要在 Seata 里配置相应的策略(只要编码正确的话一般不会出现这种情况)。第三步,数据校验完成,回滚数据,拿到它的前镜像,执行修改,完成后删除 undo_log

只要我们的总事务没有执行完成,总事务期间用到的所有全局锁都不会被释放,在并发的情况下很有效。

总结一下就是

一阶段:执行本地业务并生成回滚日志
每个微服务(分支事务)要做以下几件事:

  1. 执行业务操作(例如减库存、扣余额、创建订单);
  2. 查询并记录前镜像数据(操作前的快照);
  3. 执行 SQL 修改数据;
  4. 记录后镜像数据;
  5. 将前镜像和后镜像写入 undo_log 表;
  6. 向 TC 注册分支事务并锁定数据(记录全局锁);
  7. 提交本地事务:业务数据 + undo_log 一起提交;
  8. 将执行结果上报给 TC(成功 / 失败)。
    此时,数据已修改,但可以 “回滚”,因为 undo_log 记录了变更前后状态。

二阶段:根据 TC 指令提交或回滚
✅ 情况一:所有分支事务都成功

  1. TC 统一发出 “提交” 通知;
  2. 各服务在本地执行:
  • 删除对应的 undo_log 日志;
  • 表示数据最终确认生效;
  1. 无需其他额外操作。
    注意:提交是非常轻量的操作,只是删除日志。

❌ 情况二:某个分支事务失败,需要全局回滚

  1. TC 向所有已经成功提交的服务发送 “回滚” 指令;
  2. 每个微服务执行 “回滚事务”,包含:
  • 找日志:根据全局事务 ID(XID)+ 分支事务 ID 定位 undo_log;
  • 数据校验:
    • 把 undo_log 的 “后镜像” 与数据库当前值做对比;
    • 如果一致,说明数据没有被修改过,可以安全回滚;
    • 如果不一致,要根据配置策略判断如何处理(可能是并发或手动干预导致);
  • 数据还原:用 “前镜像” 覆盖当前数据,完成回滚;
  • 删除 undo_log,表示回滚完成。

全局锁说明
在整个全局事务未完成前(无论提交还是回滚),相关数据持有全局锁,不能被其他事务访问,确保数据一致性。

总结一句话:

Seata 的 2PC 模型中,一阶段提交业务数据 + 回滚日志,二阶段根据 TC 决定是删除日志(提交)还是回滚数据(根据日志还原),最终实现分布式事务的一致性。

分布式和微服务有什么区别?

  • 分布式是一种架构方式或工作模式,它把一个大型系统拆分成多个独立的小模块,部署在不同的机器上,通过网络协同工作。
    • 比如:用户服务在 A 机器、订单服务在 B 机器,它们通过接口通信。
  • 微服务是分布式架构的一种设计思想。它把一个完整的系统拆分成多个独立的小服务,每个服务都可以独立开发、部署和扩展。
    • 比如:用户微服务、订单微服务、支付微服务等,每个都可以单独运行、独立维护。
  • 集群强调的是物理形态,指多台机器协同处理同一个应用或任务。
    • 比如你有三台机器同时部署同一个服务,做负载均衡或高可用——这就叫集群。

分布式是架构方式,微服务是架构风格,集群是部署形态。
三者关系:
微服务通常跑在分布式架构上;
分布式系统可以通过集群来提高性能和可靠性。

为什么需要负载均衡?

负载均衡主要用于将网络请求和流量分发到多台服务器或服务实例上,从而提高系统的高可用性和性能。它能够确保系统在高并发访问下保持稳定,避免单个服务器因负载过高而导致性能下降或宕机。

负载均衡算法有哪些?

常见的负载均衡算法

负载均衡的核心目标是让请求在多台服务器之间尽量分配得更均匀,提高系统的性能和可靠性。
常见的算法主要有以下几种

1️ 轮询算法(Round Robin)
最简单的算法,按顺序把请求分配到各服务器上。
适合服务器性能相近的场景,但不考虑负载差异。

2️ 加权轮询(Weighted Round Robin)
给不同服务器分配不同权重,权重大说明性能好,处理请求也多。
常用于服务器性能差异较大的情况。

3️ 随机算法(Random)
随机选一台服务器处理请求,简单易实现。
但性能差异大的情况下容易出现“强的更忙,弱的闲”。

4️ 加权随机(Weight Random)
在随机的基础上加权,性能越好的服务器被选中的概率越高。

5️ 最少连接(Least Connection)
优先选择当前连接数最少的服务器,确保负载均衡。
特别适合请求处理时间不一致的业务,比如文件上传或接口耗时不同的场景。

6️ 哈希算法(Hash)
根据请求的某个特征(如 IP、URL、用户 ID)进行哈希计算,固定分配到某台服务器。
适合需要会话保持的场景,比如 Redis、登录服务。

一句话总结

常见负载均衡算法有:轮询、加权轮询、随机、加权随机、最少连接、哈希
轮询最简单,加权适配性能差异,最少连接更智能,哈希适合会话保持。

什么是服务雪崩?

服务雪崩是指在微服务架构或分布式系统中,由于某个服务不可用或性能下降,导致依赖它的其他服务也出现连锁故障,最终使整个系统或大部分服务不可用的现象。

要解决服务雪崩的问题就需要引入服务熔断,底层也就是断路器

断路器是一个防止雪崩的机制,当调用方 A 发现被调服务 B 表现不佳(比如慢响应 / 出错),就会暂时停止调用,等服务恢复后再恢复正常调用。

扩展-断路器原理

img

熔断降级去保护系统稳定性的工作原理(依靠断路器):

如果服务 B 是稳定的,调用就应该通过,所以断路器的默认状态是闭合状态,此时所有的远程调用都会通过。如果某一天 B 服务炸了,我们断路器就可以打开,一打开我们的调用就不会通过,A 就不会真正的发起远程调用,当 A 发请求时断路器开着,会快速得到一个错误返回,快速返回保证了请求积压不了,系统就具有很强的稳定性。

那么 B 如果哪天恢复了,A 怎么知道 B 恢复了呢?断路器有种状态就半开,会先放请求试一试就能知道 B 是否恢复了

img

断路器有 三种状态

  • Closed(关闭)
    一切正常,请求可以正常发送到服务 B。
  • Open(打开)
    服务 B 被认为不可用,所有请求都立即失败,不再发送。
  • Half-Open(半开)
    断路器试着 “放一个请求” 到服务 B 进行探测,判断是否恢复。

断路器的触发条件:

关闭状态 下,会监控一些指标:

  • 慢调用比例(比如:超过 1 秒才响应的请求)
  • 异常比例
  • 异常请求数

只有满足两个条件才会触发统计:

  1. 达到设定的 统计时长(如 5 秒)
  2. 达到 最小请求数(如 5 个请求)

举例:

  • 如果在 5 秒内有 100 个请求,其中 70 个超过了 “慢调用阈值”,就认为慢调用比例是 70%;
  • 如果这个比例超过设定的阈值(如 70%),断路器就 “打开”。

打开(Open)状态行为:

  • 一旦进入 Open 状态,所有对 B 的请求都被拒绝(快速失败);
  • 会保持打开一段 熔断时长(如 30 秒);
  • 在这段时间内,不会再尝试调用服务 B。

半开(Half-Open)状态行为:

  • 熔断时长结束后,断路器会进入半开状态;

  • 只允许一个请求

    过去试探服务 B 是否恢复;

    • 如果成功:断路器变回关闭状态,恢复正常调用;
    • 如果失败:断路器再次进入打开状态,继续熔断 30 秒。

循环机制:

断路器会在 “关闭 → 打开 → 半开 → 关闭 / 打开” 之间循环:

  • 成功 → 回到正常(关闭)
  • 失败 → 再次熔断(打开)

而且即便是关闭状态,也会继续统计指标。如果又超过阈值,就会重新触发熔断。

总结一句话:

断路器是一个防止雪崩的机制,当调用方 A 发现被调服务 B 表现不佳(比如慢响应 / 出错),就会暂时停止调用,等服务恢复后再恢复正常调用。

什么是服务熔断?

服务熔断指的是当某个服务的调用失败率持续升高时,通过中断对该服务的请求,防止系统资源被不断消耗,进而保护整个系统不受影响。

要解决服务雪崩的问题就需要引入服务熔断,底层也就是断路器(熔断器)

断路器是一个防止雪崩的机制,当调用方 A 发现被调服务 B 表现不佳(比如慢响应 / 出错),就会暂时停止调用,等服务恢复后再恢复正常调用。

扩展-断路器原理

img

熔断降级去保护系统稳定性的工作原理(依靠断路器):

如果服务 B 是稳定的,调用就应该通过,所以断路器的默认状态是闭合状态,此时所有的远程调用都会通过。如果某一天 B 服务炸了,我们断路器就可以打开,一打开我们的调用就不会通过,A 就不会真正的发起远程调用,当 A 发请求时断路器开着,会快速得到一个错误返回,快速返回保证了请求积压不了,系统就具有很强的稳定性。

那么 B 如果哪天恢复了,A 怎么知道 B 恢复了呢?断路器有种状态就半开,会先放请求试一试就能知道 B 是否恢复了

img

断路器有 三种状态

  • Closed(关闭)
    一切正常,请求可以正常发送到服务 B。
  • Open(打开)
    服务 B 被认为不可用,所有请求都立即失败,不再发送。
  • Half-Open(半开)
    断路器试着 “放一个请求” 到服务 B 进行探测,判断是否恢复。

断路器的触发条件:

关闭状态 下,会监控一些指标:

  • 慢调用比例(比如:超过 1 秒才响应的请求)
  • 异常比例
  • 异常请求数

只有满足两个条件才会触发统计:

  1. 达到设定的 统计时长(如 5 秒)
  2. 达到 最小请求数(如 5 个请求)

举例:

  • 如果在 5 秒内有 100 个请求,其中 70 个超过了 “慢调用阈值”,就认为慢调用比例是 70%;
  • 如果这个比例超过设定的阈值(如 70%),断路器就 “打开”。

打开(Open)状态行为:

  • 一旦进入 Open 状态,所有对 B 的请求都被拒绝(快速失败);
  • 会保持打开一段 熔断时长(如 30 秒);
  • 在这段时间内,不会再尝试调用服务 B。

半开(Half-Open)状态行为:

  • 熔断时长结束后,断路器会进入半开状态;

  • 只允许一个请求

    过去试探服务 B 是否恢复;

    • 如果成功:断路器变回关闭状态,恢复正常调用;
    • 如果失败:断路器再次进入打开状态,继续熔断 30 秒。

循环机制:

断路器会在 “关闭 → 打开 → 半开 → 关闭 / 打开” 之间循环:

  • 成功 → 回到正常(关闭)
  • 失败 → 再次熔断(打开)

而且即便是关闭状态,也会继续统计指标。如果又超过阈值,就会重新触发熔断。

总结一句话:

断路器是一个防止雪崩的机制,当调用方 A 发现被调服务 B 表现不佳(比如慢响应 / 出错),就会暂时停止调用,等服务恢复后再恢复正常调用。

什么是服务降级?

服务降级是一种在分布式系统微服务架构中常用的容错机制,用于在系统压力过大或部分服务出现故障时,暂时减少或关闭某些不必要的功能,从而确保核心功能的正常运行,避免系统崩溃。

什么是服务限流?

服务限流是一种流量控制策略,它通过限制每秒请求的数量(QPS)、请求频率、并发数等,来保护服务的处理能力,防止系统因为流量过大而出现性能问题或资源耗尽

Sentinel 是怎么实现限流的?

Sentinel 实现限流的核心思路是通过定义流量控制规则来保护服务。它主要通过以下方式实现限流:

  • 流量控制规则:包括设置 QPS(每秒请求数)限制、并发线程数控制等。
  • 统计与监控:它会实时统计每个资源的流量情况,并在超出设置阈值时进行流量限制(比如抛出流控异常)。
  • 分布式限流:通过与配置中心(如 Nacos、Zookeeper)结合,动态调整流量控制规则,实现跨服务的统一限流。

Sentinel 中怎么实现集群限流?

在 Sentinel 中实现集群限流,主要通过两个角色来完成:Token Server 和 Token Client。简单来说,Token Server 就是流量控制的“大脑”,它负责管理流量的请求,而 Token Client 则是“执行者”,每个服务实例都相当于是一个 Token Client,向 Token Server 请求流量的许可。

具体的过程是这样的:每当一个 Token Client 发起请求时,它会先向 Token Server 申请一个令牌。如果成功拿到令牌,Token Client 就可以继续处理该请求;如果没拿到令牌,那么就会被限流,可能会被拒绝请求或进入排队等候。

为了提高系统的可靠性,Sentinel 支持多个 Token Server。当一个 Token Server 出现故障时,系统会自动切换到其他可用的 Token Server,确保集群流量控制的不中断,增强系统的稳定性。

所以,简单来说,Sentinel 通过 Token Server 集中管理流量的请求,确保高并发情况下流量能够被有效控制,系统也能稳定运行。

什么是微服务网关?为什么需要服务网关?

微服务网关是分布式系统中的关键组件,它充当了系统的统一入口,能够有效地管理和路由不同的请求。你可以把它想象成地铁站的安检闸机,所有进入系统的请求都必须通过网关。它不仅完成了请求的转发,还承担了很多其他的功能。

首先,网关负责统一的请求路由当请求通过网关时,它会自动判断请求应该被转发到哪个服务上。此外,网关还可以结合负载均衡算法,确保集群中每个服务器的负载是均衡的。

另外,网关还能够对流量进行控制,比如它可以和像 Sentinel 这样的工具结合,实现全局的流量控制。如果系统中某个微服务的 QPS 达到限制,网关就能在入口处统一限流,避免后端系统过载。

此外,网关还承担了身份认证的任务。如果有未登录的用户请求访问受限资源,网关可以拦截并要求重新登录。它还能防止一些非法攻击,比如拦截 SQL 注入、跨站请求伪造等常见的安全问题。

最后,网关还支持协议转换。比如前端发送的请求是 JSON 格式,但后端服务需要 GRPC 协议,网关可以将数据格式转换,从而保证不同协议之间的无缝对接。

总的来说,微服务网关是微服务架构中的核心,它不仅统一了请求管理,还提升了系统的安全性、稳定性和可维护性。

Spring Cloud 可以选择哪些 API 网关?

在 Spring Cloud 中,选择 API 网关有好几种方案

  • 首先是 Spring Cloud Gateway,这是目前最推荐的选项,它基于 WebFlux 响应式编程框架,支持流量控制、路由转发、服务熔断等功能,非常适合与 Spring Cloud 的生态系统兼容,尤其在微服务架构下,它与 Nacos、Consul、OpenFeign 等微服务组件非常契合。
  • 另外,Kong 是一个高性能的 API 网关,常用于云原生架构,能够与 Spring Cloud 集成,提供强大的路由、认证、流量控制等能力,非常适合大规模的 API 管理需求。
  • Apache APISIX 也是一种开放源代码的网关,具有良好的性能,并且支持多种框架和语言,适用于需要高可扩展性和灵活性的项目。
  • 如果我们提到 Envoy,它使用 C++ 开发,适用于需要高性能、高并发的场景,虽然开发起来相对较难,但它在微服务领域的应用很广泛,尤其适合大规模的服务网格环境。
  • Nginx 作为大家熟悉的反向代理工具,也可以作为 API 网关来使用,常见于负载均衡、流量控制等,但对于更复杂的路由和管理需求来说,可能不如专用的网关灵活。
  • 最后是 Zuul,这是 Spring Cloud 早期推荐的网关,尽管它已逐渐被 Spring Cloud Gateway 所替代,但依然可以执行基本的路由和负载均衡功能。

常见的就Spring cloud GateWay和Nginx

什么是 Spring Cloud Gateway?

Spring Cloud Gateway 是 Spring Cloud 中用于处理微服务请求的网关,提供了许多强大的功能。它基于 Spring WebFlux 和 Reactor,支持高并发且低延迟的请求处理,可以有效提升服务的性能。

简单来说,Spring Cloud Gateway 扮演了类似交通指挥员的角色。它帮助将来自客户端的请求路由到正确的微服务,同时还能处理流量控制、身份验证、协议转换等任务。它的工作原理就像是你进入地铁站,先通过安检闸机,再决定你去哪个站。

主要功能:

  1. 请求路由:根据路由规则把请求转发到正确的微服务。
  2. 负载均衡:通过负载均衡算法,均衡各个微服务的请求量,避免服务器过载。
  3. 流量控制:类似 Sentinel,它可以进行流量限流,保证系统的稳定性。
  4. 身份认证:例如,网关可以验证用户是否登录,未登录的请求会被重定向到登录页面。
  5. 协议转换:如果前端和后端使用不同的协议(如 JSON 和 GRPC),网关也可以进行协议的转换。
  6. 系统监控:它可以监控请求的处理时间和访问量,用于分析系统的性能瓶颈。

总的来说,Spring Cloud Gateway 不仅是请求转发的工具,它还提供了一个集中管理微服务流量的方式,使得微服务的调用更加规范和高效。

你的项目为什么选 Spring Cloud Gateway作网关

  • 一句话概括

    • 我们需要一个“统一入口”来转发前端请求、做鉴权/限流/日志,最好还能跟微服务注册中心打通、动态路由、好扩展。Spring Cloud Gateway正好契合这些诉求。
  • 在 GQ Video 里它具体做了什么

    • 统一入口:http://localhost:7071
    • 按前缀分发到内部服务(见网关配置)
      • /web → 视频主站服务
      • /interact → 互动服务(评论/弹幕)
      • /file → 资源服务(上传/转码/文件读取)
      • /admin → 后台管理服务
    • 动态发现/配置:对接 Nacos,服务上下线/路由规则改动不需要重启。
    • 统一过滤器:
      • 自定义全局过滤器 GatewayGlobalRequestFilter 做链路日志、公共头处理等;
      • 管理端路由挂了 AdminFilter,做管理口子的额外校验;
      • 统一 CORS、去前缀 StripPrefix,出错走统一 GatewayExceptionHandler
    • 前端开发也更顺:Vite 直接把 /api 代理到 7071 网关,后端路由透明。
  • 为什么选 Spring Cloud Gateway(而不是直接 Nginx/Zuul/Kong)

    • 和 Spring 生态天然融合:拿到请求上下文、轻松接入 Spring Security、Resilience4j,写业务级过滤器更顺手(Java 代码即配置)。
    • 动态路由/灰度更容易:基于注册中心+谓词/过滤器模型,按路径、Header、权重做灰度/蓝绿都行。
    • 性能与模型合适:基于 Reactor Netty,天然异步非阻塞,吞吐和资源占用比早期 Zuul 1(Servlet 阻塞模式)更友好。
    • 可观测与治理能力:方便加统一日志、限流、熔断、重试、埋点;问题定位只盯一处入口。
    • 和 Nginx 的分工:Nginx 适合边缘层 L4/L7 转发、静态资源;Gateway 适合“贴近业务”的网关(鉴权、灰度、风控、参数改写);两者可以叠加用。
  • 给我们带来的直接收益

    • 前后端/多服务的“单一入口”,隐藏内网拓扑,降低耦合。
    • 统一的安全与流控点,保护下游(后期加限流/熔断非常方便)。
    • 动态与可灰度的路由管理,发版/回滚更稳。
    • 开发效率高:路由、过滤器都在一处维护,Java 同栈改起来更快。

总结

  • 我们选 Gateway,是为了把“路由+鉴权+流控+日志+灰度”这些通用能力统一放在网关层,并且与 Spring/Nacos 无缝协作;对 GQ Video 这种多微服务、前后端分离的项目,既省心,又能随着业务轻松演化。

说说什么是 API 网关?它有什么作用?

API 网关是一个为客户端和后端微服务之间提供统一入口的组件。它的作用是接收客户端的请求,判断请求应该转发到哪个服务,并且在转发时可以进行一系列处理,比如流量控制、认证、限流、缓存、日志记录等。

主要作用:

  1. 简化客户端调用:通过 API 网关,客户端只需要和网关打交道,避免了直接和多个后端服务沟通。这样客户端不需要知道后端服务的具体信息,比如部署位置和接口,极大简化了调用流程。
  2. 流量管理与负载均衡:API 网关可以实现负载均衡,帮助分散到多个服务器的请求,确保系统的高可用性。
  3. 请求路由与转发:网关根据配置规则将客户端请求转发到不同的后端服务上,提升系统的扩展性。
  4. 权限认证与安全控制:可以在 API 网关层面进行用户认证和权限控制,确保只有合适的用户可以访问特定的服务。
  5. 流量限制:网关可以限制特定接口的访问量,避免单个接口超负荷请求造成整个系统的崩溃。
  6. 日志与监控:API 网关也可以负责记录请求日志、处理错误监控等,帮助分析系统性能,快速定位问题。
  7. 协议转换:它还能处理不同协议之间的转换,比如客户端发出的 JSON 请求可以被转换成后端微服务所需要的 GRPC 协议,提升服务之间的兼容性。

简而言之,API 网关就像是一个“门卫”,它管理着客户端和微服务的所有交互,帮助确保系统的高效、安全和稳定运行 。

什么是漏桶什么是令牌桶?

漏桶和令牌桶都是用于流量控制的算法,它们有一个相似点:都使用了一个“桶”来控制数据流入和流出,但它们的工作原理和适用场景有所不同。

漏桶算法:

漏桶算法像一个有漏孔的水桶,水以固定速率漏出,而不管水流入的速度有多快。举个例子,假设水桶每秒钟可以漏出1滴水,那么即使前几秒没有水流进桶里,第五秒来了5滴水,漏桶只能处理1滴,剩下的请求会被拒绝。因此,漏桶算法适合于需要限制数据的平均传输速率,并确保流量平稳的场景。

img

令牌桶算法:

令牌桶算法和漏桶类似,但令牌桶的“桶”并不漏水,它只会以固定速率往桶中放入令牌。每当有请求来时,它就会去桶里取令牌。如果令牌桶里有令牌,说明可以处理请求;如果没有令牌,则请求会被拒绝或者阻塞。令牌桶的优势在于它可以处理突发流量——如果前面没有请求,令牌会一直积累,直到请求流量大幅增加时,可以用这些积累的令牌一次性处理多个请求。

img

总结:

  • 漏桶算法适合于平稳的数据流控制,确保流量按照固定速率进行传输,但无法处理突发流量。
  • 令牌桶算法则可以平滑地控制流量,并能应对突发流量,它在很多情况下比漏桶更为灵活和高效。

你可以把漏桶想象成一个水龙头,每次只放出固定量的水;而令牌桶就像一个加油站,虽然每秒钟会加一定的油,但如果前面没人加油,油就会累积,到需要的时候一次性满足需求。