»Spring Cloud Alibaba 微服务架构实战:Nacos、OpenFeign、Gateway、RabbitMQ、Sentinel、Seata 全链路解析
2026-06-192026-06-19Java11 分钟读完(约 2830 字)
微服务不是简单地把一个项目拆成多个模块,而是一套围绕服务治理、服务通信、配置管理、流量控制、消息解耦、分布式事务与可观测性建立起来的完整架构体系。
用户请求
│
▼
Nginx (反向代理)
│
▼
Spring Cloud Gateway (API 网关)
鉴权 / 路由 / 限流 / 日志 / 跨域
│
┌───────────────┼───────────────┐
▼ ▼ ▼
user-service order-service product-service
│ │ │
└─── OpenFeign 远程调用 ─────────┘
│ │ │
└───────────────┼───────────────┘
│
┌───────────┴───────────┐
▼ ▼
Nacos RabbitMQ
(注册中心 + 配置中心) (消息解耦 + 削峰)
│ │
▼ ▼
Sentinel Seata
(流量治理 + 熔断降级) (分布式事务)
│ │
└───────────┬───────────┘
▼
MySQL / Redis 集群
从单体到微服务:架构演进的内在逻辑
单体架构的黄金时代与必然瓶颈
早期项目通常采用单体架构,所有模块部署在同一个 JVM 中:
Mall ── 一个 War/Jar 包
├── user (用户模块)
├── product (商品模块)
├── order (订单模块)
├── pay (支付模块)
└── inventory (库存模块)
单体的优势(这也是它长期统治的原因):
| 维度 | 说明 |
|---|---|
| 开发简单 | IDE 一个项目即可启动全部功能 |
| 部署简单 | 打一个包,丢到 Tomcat 就完事 |
| 测试方便 | 单测 + 集成测试无需 mock 跨服务调用 |
| 事务简单 | @Transactional 搞定一切 |
但随着业务增长,四个致命缺陷逐渐暴露:
┌──────────────────────────────────────────────────────────────────┐
│ 单体架构的四大致命缺陷 │
│ │
│ ① 发布风险高 │
│ 修改订单模块的一行代码 → 整个系统重新部署 │
│ 发布失败 → 用户/商品/支付全部受影响 │
│ │
│ ② 扩容粒度粗 │
│ 秒杀活动 → 只有订单服务压力大 │
│ 但只能整体扩容 → User×3 + Product×3 + Order×3 → 资源大量浪费 │
│ │
│ ③ 技术栈锁定 │
│ 整个项目 Spring Boot + MySQL → 无法为特定场景选型 │
│ 库存模块想用 Go + Redis Stream → 不可能 │
│ │
│ ④ 代码腐化加速 │
│ 业务边界模糊 → 模块间随意引用 → 牵一发而动全身 │
└──────────────────────────────────────────────────────────────────┘
微服务的核心思想
一个服务只负责一个业务能力,独立开发、独立部署、独立扩容、独立数据库。
电商系统拆分为 6 个独立服务:
user-service → 自有数据库(user_db)
product-service → 自有数据库(product_db)
order-service → 自有数据库(order_db)
inventory-service → 自有数据库(inventory_db)
pay-service → 自有数据库(pay_db)
logistics-service → 自有数据库(logistics_db)
微服务带来的核心收益:
| 维度 | 单体 | 微服务 |
|---|---|---|
| 发布粒度 | 全量部署 | 单服务独立发布 |
| 扩容粒度 | 整体扩容 | 按需扩容(只扩订单服务) |
| 技术选型 | 统一技术栈 | 异构(Java + Go + Python) |
| 故障隔离 | 一个模块崩 = 全部崩 | 故障仅影响单个服务 |
| 团队协作 | 耦合严重 | 每个团队独立交付 |
CAP 理论:分布式系统第一性原理
所有分布式架构决策的本质,都是在 CAP 三角中做取舍:
C (Consistency)
/\
/ \
/ \
/ \
/________\
A (Availability) P (Partition Tolerance)
- C(一致性):所有节点在同一时刻看到的数据完全相同
- A(可用性):每个请求都能收到一个非错误的响应(但不保证是最新数据)
- P(分区容忍性):系统在出现网络分区时仍能继续运作
为什么 P 是必选项?
网络一定会出问题——这是分布式系统的物理定律:
杭州机房 ────X──── 上海机房
网络中断
此时必须选择 P(容忍分区)→ 剩下的 C 和 A 只能二选一:
CP 选择(放弃 A):拒绝写入,保证所有节点数据一致
AP 选择(放弃 C):允许写入,分区恢复后再同步
Nacos 的双模设计:同时支持 AP 和 CP
Nacos 的核心设计精髓在于区分了临时实例和永久实例:
| 模式 | 实例类型 | 配置 | CAP | 检测机制 | 适用场景 |
|---|---|---|---|---|---|
| AP | 临时实例 | ephemeral: true | 优先可用性 | 心跳检测(UDP) | 订单/用户/商品等业务服务 |
| CP | 永久实例 | ephemeral: false | 优先一致性 | Raft 协议同步 | 配置管理、核心元数据 |
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
ephemeral: true # true=AP(临时实例), false=CP(永久实例)
Nacos 注册中心:服务寻址的根基
为什么需要注册中心?
传统硬编码方式:
http://192.168.10.100:8081/user/1
↑
IP 变了怎么办?
扩容到 5 个节点怎么办?
注册中心方式:
http://user-service/user/1
↑
只需服务名,其余由注册中心 + 负载均衡自动处理
服务注册与发现的完整流程
┌──────────────────────────────────────────────────────────────────┐
│ Nacos 注册发现流程 │
│ │
│ ① user-service 启动 │
│ │ │
│ ▼ │
│ ② 向 Nacos Server 发送注册请求(IP + Port + 元数据) │
│ │ │
│ ▼ │
│ ③ Nacos Server 维护服务列表 │
│ user-service: [192.168.1.10:8081, 192.168.1.11:8081] │
│ │ │
│ ▼ │
│ ④ user-service 每 5 秒发送心跳包(续约) │
│ │ │
│ ▼ │
│ ⑤ order-service 调用 user-service │
│ → 从 Nacos 拉取 user-service 实例列表 │
│ → LoadBalancer 选择目标实例 │
│ → 发起 HTTP 调用 │
│ │
│ ⑥ 若 15 秒无心跳(3 次间隔)→ Nacos 标记不健康 │
│ 若 30 秒无心跳 → Nacos 摘除该实例 │
└──────────────────────────────────────────────────────────────────┘
核心配置
# user-service 的 bootstrap.yml
spring:
application:
name: user-service # 服务名,调用方通过它寻址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: dev # 命名空间隔离(开发/测试/生产)
group: DEFAULT_GROUP # 分组隔离
cluster-name: HZ # 集群名(同集群优先调用)
Nacos 配置中心
注册中心解决了"找得到",配置中心解决了"改得动"。Nacos 将两者合二为一:
# bootstrap.yml(优先级高于 application.yml)
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: dev
file-extension: yaml
group: DEFAULT_GROUP
shared-configs: # 共享配置(跨服务复用)
- data-id: common-redis.yaml
group: DEFAULT_GROUP
refresh: true # 自动刷新
// 动态刷新:修改配置后无需重启服务
@RestController
@RefreshScope // ← 关键注解:Nacos 配置变更时自动刷新此 Bean
public class UserController {
@Value("${user.max-login-retry:3}")
private int maxRetry;
@GetMapping("/config")
public int getMaxRetry() {
return maxRetry; // Nacos 改值后,这里实时生效
}
}
OpenFeign:声明式服务调用
为什么不用 RestTemplate?
// RestTemplate 方式:大量硬编码 + 字符串拼接
String url = "http://user-service/user/" + userId;
User user = restTemplate.getForObject(url, User.class);
// OpenFeign 方式:面向接口,像调本地方法一样调远程服务
@FeignClient("user-service")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
// 调用
User user = userClient.findById(1L); // 一行搞定
OpenFeign 底层原理
userClient.findById(1L)
│
▼
JDK 动态代理(FeignInvocationHandler)
│
▼
根据注解构造 Request(GET /user/1, Headers, Body)
│
▼
LoadBalancer 从 Nacos 选一个实例(192.168.1.10:8081)
│
▼
HTTP Client(默认 URLConnection,建议换 Apache HttpClient)
│
▼
接收 Response → 反序列化为 User 对象
生产级配置与拦截器
// 请求拦截器:自动透传认证 Token
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 从当前请求上下文中获取 Token,自动注入到 Feign 请求头
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
String token = attributes.getRequest().getHeader("Authorization");
if (StringUtils.hasText(token)) {
template.header("Authorization", token);
}
}
}
}
spring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 5000 # 连接超时 5s
read-timeout: 10000 # 读取超时 10s
logger-level: BASIC # 日志级别
user-service: # 针对特定服务的单独配置
connect-timeout: 2000
// Feign + Sentinel 熔断兜底
@FeignClient(name = "user-service", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
@Component
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable cause) {
return id -> {
log.error("user-service 调用失败,id: {}", id, cause);
return User.DEFAULT; // 返回兜底对象
};
}
}
Spring Cloud Gateway:API 网关
网关的四大核心职责
┌─────────────────┐
鉴权 │ Spring Cloud │ 路由
JWT Token 校验 ──→│ Gateway │──→ Path 匹配转发
│ │
限流 │ 全局过滤器链 │ 日志
RequestRateLimiter│ │ 访问日志 + 慢查询告警
└─────────────────┘
路由配置
spring:
cloud:
gateway:
routes:
# 路由 1:用户服务(负载均衡)
- id: user-service
uri: lb://user-service # lb:// = 走 LoadBalancer
predicates:
- Path=/user/**
filters:
- StripPrefix=0
# 路由 2:订单服务(含认证)
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter # 限流
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
# 路由 3:WebSocket(不同协议)
- id: websocket-route
uri: lb:ws://chat-service
predicates:
- Path=/ws/**
全局过滤器:统一鉴权
@Component
@Order(-1) // 优先级最高
public class AuthGlobalFilter implements GlobalFilter {
// 白名单:无需鉴权的路径
private static final List<String> WHITE_LIST = List.of(
"/login", "/register", "/captcha", "/public/"
);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
// 白名单放行
if (WHITE_LIST.stream().anyMatch(path::startsWith)) {
return chain.filter(exchange);
}
// Token 校验
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (!StringUtils.hasText(token)) {
return unauthorized(exchange, "未登录");
}
try {
// 解析 JWT,将用户信息放入请求头传给下游
Claims claims = JwtUtil.parseToken(token);
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-User-Id", claims.get("userId", String.class))
.header("X-Username", claims.get("username", String.class))
.build();
return chain.filter(exchange.mutate().request(request).build());
} catch (Exception e) {
return unauthorized(exchange, "Token 无效或已过期");
}
}
private Mono<Void> unauthorized(ServerWebExchange exchange, String msg) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] bytes = ("{\"msg\":\"" + msg + "\"}").getBytes(StandardCharsets.UTF_8);
return exchange.getResponse()
.writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(bytes)));
}
}
RabbitMQ:消息驱动的服务解耦
同步 vs 异步:一个下单场景的对比
同步调用(阻塞等待,耗时累加):
下单 → 发短信(1s) → 发邮件(1s) → 更新积分(1s) = 3s+
↑ 用户等 3 秒,体验极差
异步解耦(消息驱动,并行处理):
下单 → MQ → 短信服务
→ 积分服务 ← 三个消费者并行处理
→ 邮件服务
↑ 订单接口 50ms 返回
RabbitMQ 五种交换机与路由模型
| 模型 | 交换机类型 | 路由逻辑 | 典型场景 |
|---|---|---|---|
| Simple | —(默认) | 直连队列 | 单消费者处理任务 |
| Work Queue | —(默认) | 多消费者竞争消费 | 批量任务分发 |
| Fanout | fanout | 广播到所有绑定队列 | 配置刷新通知、日志广播 |
| Direct | direct | 按 Routing Key 精确匹配 | 按业务类型路由 |
| Topic | topic | 按通配符模糊匹配(* #) | 企业最常用,灵活路由 |
Topic 模式:企业最常用
@Configuration
public class RabbitMqTopicConfig {
// ===== 交换机和队列定义 =====
@Bean
public TopicExchange orderExchange() {
return new TopicExchange("order.exchange");
}
@Bean
public Queue orderCreateQueue() {
return QueueBuilder.durable("order.create.queue")
.ttl(60000) // 消息 TTL 60 秒
.deadLetterExchange("dlx.exchange") // 死信交换机
.deadLetterRoutingKey("dlx.order") // 死信路由键
.build();
}
@Bean
public Queue orderCancelQueue() {
return QueueBuilder.durable("order.cancel.queue").build();
}
// ===== 绑定关系(支持通配符) =====
@Bean
public Binding bindOrderCreate() {
return BindingBuilder.bind(orderCreateQueue())
.to(orderExchange())
.with("order.create"); // 精确匹配
}
@Bean
public Binding bindOrderAll() {
return BindingBuilder.bind(orderCancelQueue())
.to(orderExchange())
.with("order.*"); // 匹配 order.create / order.cancel / order.pay
}
}
消息可靠性保障三件套
┌──────────────────────────────────────────────────────────────┐
│ 消息可靠性保障全景 │
│ │
│ 生产者确认(Publisher Confirm) │
│ ├── 消息到达 Exchange 回调 confirmCallback │
│ └── 消息无法路由 → returnCallback → 记录失败日志 │
│ │
│ 消息持久化 │
│ ├── 队列持久化(durable = true) │
│ └── 消息持久化(MessageProperties.PERSISTENT_TEXT_PLAIN) │
│ │
│ 消费者确认(Consumer Ack) │
│ ├── 手动确认(acknowledge-mode: manual) │
│ ├── 消费失败 → nack → 重新入队 │
│ └── 多次重试失败 → 死信队列(DLX)→ 人工介入 │
└──────────────────────────────────────────────────────────────┘
@Component
@Slf4j
public class OrderCreateConsumer {
@RabbitListener(queues = "order.create.queue")
public void handle(OrderMessage message, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long tag) {
try {
// 业务处理
orderService.createOrder(message);
// 手动确认
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("订单创建消费失败,消息: {}", message, e);
try {
// 重新入队(只重试一次,避免无限循环)
channel.basicNack(tag, false, true);
} catch (IOException ex) {
log.error("nack 失败", ex);
}
}
}
}
延时队列(基于死信交换机 + TTL)
// 下单 30 分钟未支付 → 自动取消
// 原理:发消息到无消费者的队列,设 TTL → 过期后自动投递到死信交换机
@Bean
public Queue orderDelayQueue() {
return QueueBuilder.durable("order.delay.queue")
.ttl(30 * 60 * 1000) // 30 分钟
.deadLetterExchange("order.exchange") // 过期后发到这里
.deadLetterRoutingKey("order.cancel") // 用 cancel 路由键
.build();
}
// 消费者监听死信队列 → 处理超时取消
@RabbitListener(queues = "order.cancel.queue")
public void handleOrderCancel(OrderMessage message) {
// 检查订单状态,若仍是"待支付"则取消
orderService.cancelIfUnpaid(message.getOrderId());
}
Sentinel:流量治理的最后一道防线
Sentinel 的三大核心能力
┌──────────────────────────────────────────────────────┐
│ Sentinel 流量治理 │
│ │
│ 流控(Flow Control) │
│ QPS > 1000 → 直接拒绝 / Warm Up / 匀速排队 │
│ │
│ 熔断(Circuit Breaker) │
│ 慢调用比例 > 50% / 异常比例 > 50% → 熔断 N 秒 │
│ │
│ 降级(Fallback) │
│ 被流控 / 被熔断 / 服务异常 → 返回兜底结果 │
└──────────────────────────────────────────────────────┘
代码实现
@Service
public class OrderService {
// 资源名 + 流控规则 + 降级兜底
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlockHandler", // 流控/熔断兜底
fallback = "createOrderFallback" // 异常兜底
)
public Order createOrder(OrderDTO dto) {
// 核心业务逻辑
return orderMapper.insert(dto);
}
// 被流控或熔断时走这个方法
public Order createOrderBlockHandler(OrderDTO dto, BlockException e) {
log.warn("创建订单被限流/熔断,dto: {}", dto);
throw new BizException("系统繁忙,请稍后重试");
}
// 业务异常时走这个方法
public Order createOrderFallback(OrderDTO dto, Throwable e) {
log.error("创建订单异常,dto: {}", dto, e);
throw new BizException("下单失败");
}
}
Sentinel 控制台规则配置
Sentinel Dashboard(sentinel-dashboard.jar)→ 可视化配置规则
流控规则配置示例:
资源名:createOrder
阈值类型:QPS
阈值:1000
流控模式:直接
流控效果:快速失败 / Warm Up / 排队等待
熔断规则配置示例:
资源名:getProductDetail
熔断策略:慢调用比例
最大 RT:200ms
比例阈值:0.5(超过 50% 请求 >200ms 则熔断)
熔断时长:10s
最小请求数:5
网关层 + Sentinel 联动
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter # 网关层限流(搭配 Redis)
args:
redis-rate-limiter:
replenishRate: 100 # 每秒 100 个令牌
burstCapacity: 200 # 突发容量 200
Seata:分布式事务的工程解法
分布式事务的经典困境
下单流程涉及 3 个独立的数据库:
订单服务 → order_db → INSERT 订单记录 ✅ 成功
库存服务 → inventory_db → UPDATE 扣减库存 ❌ 失败!
账户服务 → account_db → UPDATE 扣减余额 ⏸️ 未执行
此时数据已不一致:
订单写着"已下单",但库存没扣,钱也没扣!
@Transactional 只能控制一个数据库,跨服务跨库时无能为力。
Seata AT 模式:最广泛使用的方案
Seata 架构三要素:
┌──────────────────────────────────────────────────────────┐
│ Seata AT 模式架构 │
│ │
│ TC (Transaction Coordinator) │
│ Seata Server — 事务协调者,独立部署 │
│ 负责全局事务的开启、提交、回滚 │
│ │
│ TM (Transaction Manager) │
│ 事务发起方(如 OrderService) │
│ 向 TC 注册全局事务,决定提交或回滚 │
│ │
│ RM (Resource Manager) │
│ 各个数据库的资源管理器(如 InventoryService) │
│ 执行分支事务 + 上报状态 + 执行 Undo Log │
└──────────────────────────────────────────────────────────┘
AT 模式执行流程:
一阶段(执行):
① TM 向 TC 注册全局事务
② 各 RM 执行业务 SQL
③ 各 RM 自动记录 Undo Log(Before Image + After Image)
④ 各 RM 上报执行结果给 TC
二阶段(提交或回滚):
全部成功 → TC 通知各 RM 异步删除 Undo Log
任一失败 → TC 通知各 RM 根据 Undo Log 反向补偿回滚
核心配置
spring:
cloud:
alibaba:
seata:
tx-service-group: my_tx_group # 事务组名,与 seata-server 配置一致
seata:
registry:
type: nacos # 注册中心类型
nacos:
server-addr: 127.0.0.1:8848
namespace: ""
group: SEATA_GROUP
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
// 业务代码:只需加 @GlobalTransactional 注解
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private InventoryClient inventoryClient;
@Autowired
private AccountClient accountClient;
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
@Override
public Long createOrder(OrderDTO dto) {
// 1. 创建订单(本地事务)
Order order = new Order();
order.setUserId(dto.getUserId());
order.setAmount(dto.getAmount());
orderMapper.insert(order);
// 2. 扣减库存(远程调用 → Seata 自动代理为分支事务)
inventoryClient.deduct(dto.getProductId(), dto.getQuantity());
// 3. 扣减余额(远程调用 → Seata 自动代理为分支事务)
accountClient.deduct(dto.getUserId(), dto.getAmount());
return order.getId();
// 若步骤 2 或 3 抛出异常 → Seata 自动回滚步骤 1 的数据
}
}
Seata 模式对比
| 模式 | 原理 | 性能 | 侵入性 | 适用场景 |
|---|---|---|---|---|
| AT | 自动生成 Undo Log + 反向补偿 | 中 | 无(自动代理) | 通用,企业首选 |
| TCC | Try-Confirm-Cancel 三阶段 | 高 | 高(需手写三方法) | 金融、对一致性要求极高 |
| Saga | 正向执行 + 补偿回滚 | 高 | 中 | 长事务、多服务编排 |
| XA | 两阶段提交协议(数据库原生) | 低 | 无 | 传统关系型数据库 |
可观测性:生产环境的眼睛
三大支柱
| 维度 | 解决的问题 | 技术选型 |
|---|---|---|
| 日志(Logging) | 某行代码发生了什么? | ELK(Elasticsearch + Logstash + Kibana) |
| 指标(Metrics) | 系统整体有多健康? | Prometheus + Grafana |
| 链路追踪(Tracing) | 一个请求在分布式系统中如何流转? | SkyWalking / Zipkin |
SkyWalking 链路追踪
用户请求 /order/create
│
▼ Gateway (15ms)
│
▼ OrderService.createOrder() (120ms)
│ ├── inventoryClient.deduct() (45ms)
│ │ └── MySQL UPDATE (30ms)
│ ├── accountClient.deduct() (35ms)
│ │ └── MySQL UPDATE (25ms)
│ └── MySQL INSERT (10ms)
│
▼ 响应 200 (168ms)
通过 SkyWalking UI,可以清楚看到每一步耗时,快速定位慢节点。
企业级微服务实践清单
服务拆分原则
| 原则 | 正确做法 | 错误做法 |
|---|---|---|
| 高内聚低耦合 | 按业务域拆分(用户/订单/商品) | 按技术层拆分(Controller/Service/Dao 各自成服务) |
| 独立数据库 | 每个服务独享数据库 | 多个服务共享一个数据库 |
| 禁止跨服务查表 | 通过 API 调用获取数据 | 直接 JOIN 另一个服务的表 |
| 接口适度 | 一个服务 30-50 个接口 | 一个服务 300 个接口(伪微服务) |
调用链路选择
同步调用(强一致) → OpenFeign
异步解耦(最终一致)→ RabbitMQ
削峰填谷(缓冲) → RabbitMQ / RocketMQ
事务场景选择
单服务、单库 → @Transactional(本地事务)
跨服务、强一致 → Seata AT / TCC
跨服务、最终一致 → MQ + 本地消息表
总结
Spring Cloud Alibaba 生态的核心组件矩阵:
┌──────────────────────────────────────────────┐
│ Spring Cloud Alibaba 全家桶 │
│ │
│ 服务治理 ── Nacos (注册中心 + 配置中心) │
│ 服务调用 ── OpenFeign (声明式 HTTP 客户端) │
│ 负载均衡 ── LoadBalancer (客户端负载均衡) │
│ API 网关 ── Gateway (路由 + 鉴权 + 限流) │
│ 流量治理 ── Sentinel (流控 + 熔断 + 降级) │
│ 消息驱动 ── RabbitMQ (异步解耦 + 削峰) │
│ 分布式事务 ── Seata (AT/TCC/Saga) │
│ 链路追踪 ── SkyWalking(全链路追踪) │
│ 监控告警 ── Prometheus + Grafana │
└──────────────────────────────────────────────┘
记住一条主线:Nacos 让你找到服务 → OpenFeign 让你调用服务 → Gateway 守住入口 → Sentinel 防住洪峰 → RabbitMQ 解耦异步 → Seata 保证数据一致 → SkyWalking 看清一切。