第31课:微服务消息驱动(RabbitMQ/RocketMQ)适配与解耦实战

文章目录

    • 一、开篇:第30课留下的"同步之痛"
    • 二、消息异步解耦的核心价值
      • [2.1 同步调用的三大痛点](#2.1 同步调用的三大痛点)
      • [2.2 异步解耦架构设计](#2.2 异步解耦架构设计)
      • [2.3 Spring Cloud Stream统一编程模型](#2.3 Spring Cloud Stream统一编程模型)
    • 三、RocketMQ核心概念与部署
      • [3.1 RocketMQ 5.x架构](#3.1 RocketMQ 5.x架构)
      • [3.2 消息模型:集群消费 vs 广播消费](#3.2 消息模型:集群消费 vs 广播消费)
    • 四、可靠消息投递:RocketMQ事务消息实战
      • [4.1 普通消息的"一致性缺口"](#4.1 普通消息的“一致性缺口”)
      • [4.2 事务消息的两阶段提交原理](#4.2 事务消息的两阶段提交原理)
      • [4.3 Spring Cloud Stream集成事务消息](#4.3 Spring Cloud Stream集成事务消息)
      • [4.4 生产者端可靠投递保障](#4.4 生产者端可靠投递保障)
      • [4.5 Broker端可靠投递保障](#4.5 Broker端可靠投递保障)
    • 五、消费幂等实战
      • [5.1 为什么消费端必须幂等](#5.1 为什么消费端必须幂等)
      • [5.2 四种幂等方案](#5.2 四种幂等方案)
      • [5.3 基于Redis SETNX的消费幂等](#5.3 基于Redis SETNX的消费幂等)
    • 六、死信队列实战
      • [6.1 死信队列的核心概念](#6.1 死信队列的核心概念)
      • [6.2 死信队列配置](#6.2 死信队列配置)
      • [6.3 死信消费者独立部署](#6.3 死信消费者独立部署)
      • [6.4 死信队列监控](#6.4 死信队列监控)
    • 七、RabbitMQ与RocketMQ选型对比
      • [7.1 核心差异对照](#7.1 核心差异对照)
      • [7.2 选型决策框架](#7.2 选型决策框架)
    • 八、生产环境关键配置与踩坑指南
      • [8.1 消费者端可靠消费配置](#8.1 消费者端可靠消费配置)
      • [8.2 踩坑指南](#8.2 踩坑指南)
    • 九、课后作业
    • 十、阶段总结与下节预告
  • [🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航](#🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航)

适配版本 :RocketMQ 5.3.1、Spring Cloud Stream 4.x、Spring Cloud Alibaba 2025.1.0.0、Spring Cloud 2025.1.3(Oakwood)、Spring Boot 4.0.8、JDK 21

课程定位:微服务高阶阶段收官,从消息异步解耦到可靠投递,从消费幂等到死信队列,构建完整的消息驱动架构

一、开篇:第30课留下的"同步之痛"

第30课我们完成了Seata AT模式分布式事务的完整实战。@GlobalTransactional注解让跨服务的数据库操作实现了强一致性回滚------库存不足时订单自动回滚,数据不会"飘"。但Seata有一个明确的适用边界:它解决的是"短事务"的一致性问题,事务周期通常在秒级以内。

考虑一个更长的事务场景:用户下单成功后,需要扣减库存、生成物流单、发放积分、发送短信通知。这四个操作分布在四个不同的服务中,如果全部纳入Seata全局事务,会带来两个问题:性能急剧下降 (全局锁持有时间过长),以及可用性降低(任何一个服务不可用,整个全局事务都会阻塞)。

更关键的是,这些操作之间并不需要强一致性 。积分晚到几秒、短信晚发几秒,对用户来说完全可以接受。真正重要的是:订单创建成功后,这些后续操作最终一定要执行 ------这就是最终一致性。

消息队列 正是实现最终一致性的核心方案。第29课的Spring事件是单JVM内 的解耦,消息队列则是跨服务的解耦。两者的关系是互补的:Spring事件处理服务内的模块解耦,消息队列处理服务间的异步通信。

Spring Cloud Alibaba 2025.1.0.0正式适配了RocketMQ 5.3.1,而Spring Cloud Stream 4.x提供了统一的消息编程模型。本课将从消息异步解耦的痛点讲起,深入RocketMQ事务消息的可靠投递机制,实战消费幂等和死信队列,最后对比RabbitMQ与RocketMQ的选型标准。

二、消息异步解耦的核心价值

2.1 同步调用的三大痛点

回顾第16课的订单创建场景,我们用Seata保证了强一致性。但在真实的大促场景中,同步调用还会暴露出三个更深层的痛点:

痛点一:吞吐量受限于最慢的环节。 订单服务同步调用库存、积分、短信三个服务,总耗时等于三者之和。即使库存和积分只需100ms,短信服务需要300ms,整个下单接口的响应时间就至少是500ms。根据2025年的行业数据,采用异步消息队列后,订单系统的吞吐量可提升3-5倍。

痛点二:级联故障无法隔离。 短信服务如果因运营商网关故障而不可用,订单服务调用短信的超时会导致线程池被占满,进而拖垮库存和积分的调用------这就是第21课讲过的雪崩。

痛点三:流量峰值无法缓冲。 秒杀场景下瞬时流量可能是日常的100倍。同步调用无法"存储"请求,请求到来时必须立即处理,否则就丢失。消息队列天然具备削峰填谷能力------将瞬时洪峰写入队列,消费者按自己的处理能力匀速消费。

2.2 异步解耦架构设计

基于消息队列的订单创建流程如下:

复制代码
用户请求 → 订单服务
    │
    ├─ ① 创建订单(本地事务)
    ├─ ② 发送"订单已创建"消息到MQ
    │
    ▼
  返回响应(用户立即得到结果,无需等待下游)
    │
    ▼
  ┌─────────────────────────────────────┐
  │           RocketMQ Topic             │
  │           "order-created"            │
  └──────────┬──────────┬───────────────┘
             │          │
      ┌──────┴──┐  ┌────┴────┐  ┌────┴────┐
      │库存服务 │  │积分服务 │  │短信服务 │
      │消费者   │  │消费者   │  │消费者   │
      └─────────┘  └─────────┘  └─────────┘

核心变化:订单服务只负责"创建订单"和"发送消息",下游服务各自独立消费。订单服务的响应时间从500ms降至50ms(仅本地事务+发送消息),下游服务的故障不会影响订单创建。

2.3 Spring Cloud Stream统一编程模型

Spring Cloud Stream的核心价值在于提供了统一的消息编程模型。开发者无需关心底层使用的是RocketMQ、Kafka还是RabbitMQ,通过简单的配置和注解就能实现消息的发布和订阅。当企业需要更换消息中间件时,只需更换Binder依赖和少量配置,业务代码无需修改。

函数式编程模型(Spring Cloud Stream 4.x推荐) :

java 复制代码
@Configuration
public class OrderMessageConfig {

    // 生产者:将订单创建消息发送到 output 通道
    @Bean
    public Supplier<OrderCreatedEvent> orderCreated() {
        return () -> null;  // 由业务代码通过 StreamBridge 触发
    }

    // 消费者:从 input 通道接收订单创建消息
    @Bean
    public Consumer<OrderCreatedEvent> handleOrderCreated() {
        return event -> {
            log.info("处理订单创建事件: orderNo={}", event.getOrderNo());
            // 库存扣减、积分发放等业务逻辑
        };
    }
}

传统注解模型(兼容旧项目) :

java 复制代码
@EnableBinding(OrderProcessor.class)
public class OrderMessageListener {

    @StreamListener(OrderProcessor.INPUT)
    public void handleOrderCreated(OrderCreatedEvent event) {
        // 业务逻辑
    }
}

public interface OrderProcessor {
    String INPUT = "order-input";
    String OUTPUT = "order-output";

    @Input(INPUT)
    SubscribableChannel input();

    @Output(OUTPUT)
    MessageChannel output();
}

三、RocketMQ核心概念与部署

3.1 RocketMQ 5.x架构

RocketMQ 5.x相比4.x最大的架构变化是引入了Proxy层 (gRPC + HTTP双协议)和无状态Broker部署,真正实现了云原生化。Proxy层的关键创新在于:生产者/消费者只与Proxy通信,Broker内部实现对客户端透明,扩缩容不影响业务。

核心概念:

概念 含义 类比
NameServer 注册中心,维护Topic和Broker的路由信息 Nacos的注册中心角色
Broker 消息存储和转发节点 数据库服务器
Topic 消息的逻辑分类 数据库的表
Tag 消息的二级分类,用于过滤 表中的标签列
ConsumerGroup 消费者组,同组内消费者分担消息 线程池中的工作线程
Offset 消费进度,标识消费者消费到哪条消息 书签

3.2 消息模型:集群消费 vs 广播消费

消费模式 行为 适用场景
集群消费(默认) 同组消费者分担消息,每条消息只被组内一个消费者消费 订单处理、库存扣减
广播消费 同组每个消费者都收到全量消息 配置刷新、缓存更新

关键理解 :集群消费模式下,如果订单服务部署了3个实例,3个实例属于同一个ConsumerGroup,那么一条订单消息只会被其中一个实例消费。这天然实现了消费端的负载均衡。

四、可靠消息投递:RocketMQ事务消息实战

4.1 普通消息的"一致性缺口"

使用普通消息时,存在一个经典的一致性缺口:本地事务和消息发送不是原子的。如果本地事务提交成功,但消息发送失败,下游服务收不到消息,数据不一致;如果消息发送成功,但本地事务回滚,下游服务收到了不该存在的消息,同样不一致。

第16课我们学过"本地消息表"方案来解决这个问题。但RocketMQ提供了更优雅的原生方案------事务消息。

4.2 事务消息的两阶段提交原理

RocketMQ事务消息基于二阶段提交实现,流程分为两个阶段:

阶段一:发送半事务消息并执行本地事务。

复制代码
① 生产者发送半事务消息(Half Message)到 Broker
    │  此时消息对消费者不可见
    ▼
② Broker 持久化半事务消息,返回 Ack 确认
    │
    ▼
③ 生产者执行本地事务(如:写订单库)
    │
    ▼
④ 生产者根据本地事务结果,向 Broker 发送二次确认
    │  Commit → 消息可投递,消费者可见
    │  Rollback → 消息删除,消费者不可见
    │  Unknown → 等待回查

阶段二:消息回查(容错机制)。

如果生产者发送二次确认时网络中断,或生产者应用重启,Broker 未收到确认结果,会触发消息回查:Broker 端会通过扫描发现某条消息长期处于"半事务消息"状态,主动向生产者询问该消息的最终状态。生产者检查本地事务的最终结果后,再次提交二次确认。

完整交互流程:

复制代码
生产者                    Broker                   消费者
   │                        │                        │
   │──① 半事务消息─────────►│                        │
   │◄──② Ack───────────────│                        │
   │                        │                        │
   │──③ 执行本地事务        │                        │
   │                        │                        │
   │──④ Commit/Rollback───►│                        │
   │                        │──⑤ 投递消息──────────►│
   │                        │                        │
   │◄──⑥ 消息回查───────────│  (若④丢失)            │
   │──⑦ 回查结果───────────►│                        │

4.3 Spring Cloud Stream集成事务消息

生产者端配置:

java 复制代码
@Configuration
public class TransactionalProducerConfig {

    @Bean
    public TransactionMQProducer transactionMQProducer() throws MQClientException {
        TransactionMQProducer producer = new TransactionMQProducer("order-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.setTransactionListener(new OrderTransactionListener());
        producer.start();
        return producer;
    }
}

public class OrderTransactionListener implements TransactionListener {

    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            // 解析消息体,执行本地事务
            OrderCreatedEvent event = JSON.parseObject(
                    new String(msg.getBody()), OrderCreatedEvent.class);
            orderMapper.insert(event.getOrder());
            return LocalTransactionState.COMMIT_MESSAGE;
        } catch (Exception e) {
            log.error("本地事务执行失败", e);
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }

    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        // Broker 回查:检查本地事务是否执行成功
        String orderNo = msg.getUserProperty("orderNo");
        Order order = orderMapper.selectByOrderNo(orderNo);
        return order != null
                ? LocalTransactionState.COMMIT_MESSAGE
                : LocalTransactionState.ROLLBACK_MESSAGE;
    }
}

发送事务消息:

java 复制代码
@Service
public class OrderService {

    @Autowired
    private TransactionMQProducer transactionMQProducer;

    public void createOrder(OrderCreateRequest request) throws Exception {
        OrderCreatedEvent event = new OrderCreatedEvent();
        event.setOrderNo(IdUtils.generateOrderNo());
        event.setProductId(request.getProductId());
        event.setQuantity(request.getQuantity());

        Message msg = new Message("order-created", "CREATE",
                event.getOrderNo(), JSON.toJSONBytes(event));
        msg.putUserProperty("orderNo", event.getOrderNo());

        // 发送事务消息:Broker 会等待本地事务结果
        transactionMQProducer.sendMessageInTransaction(msg, null);
    }
}

4.4 生产者端可靠投递保障

除了事务消息,生产者端还需要配置同步发送和重试机制:

yaml 复制代码
spring:
  cloud:
    stream:
      rocketmq:
        binder:
          name-server: 127.0.0.1:9876
        bindings:
          order-created-out-0:
            producer:
              group: order-producer-group
              send-message-timeout: 3000        # 发送超时3秒
              retry-times-when-send-failed: 2   # 失败重试2次
              retry-next-server: true           # 重试时切换Broker

同步发送 :send()方法会阻塞直到收到Broker的ACK。重试机制 :默认重试2次,可通过retry-times-when-send-failed调整。

4.5 Broker端可靠投递保障

Broker端的可靠性配置(broker.conf):

properties 复制代码
# 同步刷盘:消息写入磁盘后才返回 ACK
flushDiskType = SYNC_FLUSH

# 同步双写:主从同步,从节点确认写入后才返回 ACK
brokerRole = SYNC_MASTER

同步刷盘 保证了消息在Broker重启后不丢失;同步双写 保证了主节点宕机后消息不丢失。两者的代价是性能下降------异步刷盘(ASYNC_FLUSH)性能更高但可能丢消息。生产环境建议:核心业务使用同步刷盘+同步双写,非核心业务使用异步刷盘。

五、消费幂等实战

5.1 为什么消费端必须幂等

RocketMQ的消息投递保证是 "至少一次(At Least Once)" ------消息不会丢失,但可能重复。重复的来源有三种:

来源 原因
生产者重试 发送超时后重试,但第一次实际已成功
Broker重投 消费者处理成功但ACK丢失,Broker重新投递
消费者重启 消费进度未及时提交,重启后从旧Offset重新消费

结论 :消费端必须实现幂等,无论消息投递几次,业务结果都一致。

5.2 四种幂等方案

方案 实现 适用场景
唯一索引 数据库唯一约束,重复插入抛异常 低频关键业务
状态机 UPDATE ... WHERE status = '前置状态' 订单、支付等有状态业务
Redis SETNX SETNX bizKey 判断是否已处理 MQ消费、事务补偿
Token机制 消息携带唯一Token,处理前校验 跨服务调用

第16课已详细讲解过这四种方案,本课重点演示在RocketMQ消费场景中的实战应用。

5.3 基于Redis SETNX的消费幂等

java 复制代码
@Component
@RocketMQMessageListener(
        topic = "order-created",
        consumerGroup = "order-consumer-group",
        consumeMode = ConsumeMode.CONCURRENTLY
)
public class OrderCreatedConsumer implements RocketMQListener<OrderCreatedEvent> {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private StockService stockService;

    private static final String IDEMPOTENT_KEY = "mq:idempotent:order:";

    @Override
    public void onMessage(OrderCreatedEvent event) {
        String bizKey = IDEMPOTENT_KEY + event.getOrderNo();

        // 1. 幂等校验:SETNX 原子操作
        Boolean success = redisTemplate.opsForValue()
                .setIfAbsent(bizKey, "processing", 24, TimeUnit.HOURS);

        if (Boolean.FALSE.equals(success)) {
            log.info("消息重复消费,已忽略: orderNo={}", event.getOrderNo());
            return;
        }

        try {
            // 2. 执行业务逻辑
            stockService.decreaseStock(event.getProductId(), event.getQuantity());

            // 3. 标记处理成功
            redisTemplate.opsForValue().set(bizKey, "success", 24, TimeUnit.HOURS);
        } catch (Exception e) {
            // 4. 处理失败,删除Key允许重试
            redisTemplate.delete(bizKey);
            throw e;
        }
    }
}

为什么用SETNX而非"先GET再SET"? 第16课详细解释过:SETNX是原子操作,在高并发下不会出现两个线程同时通过校验的竞态条件。

六、死信队列实战

6.1 死信队列的核心概念

死信队列(Dead Letter Queue, DLQ)用于存储那些消费失败且达到最大重试次数的消息。关键特性包括:

特性 说明
命名规则 %DLQ%{consumerGroup},按消费者组自动创建
触发条件 消息消费失败次数达到最大重试阈值(默认16次)
消费者隔离 死信消息不会被原消费者组再次消费,需新建消费者组单独订阅DLQ
保留时间 默认保留3天,超时自动清理

为什么需要死信队列? 当一条消息因数据格式错误、依赖服务不可用等原因反复消费失败时,无限重试会阻塞后续消息的消费,形成"毒丸消息"。死信队列将这类消息"隔离"出来,让正常消息继续流动,同时保留失败消息供后续人工排查或自动补偿。

6.2 死信队列配置

消费者配置:

yaml 复制代码
spring:
  rocketmq:
    consumer:
      group: order-consumer-group
      consume-mode: CLUSTERING
      consume-thread-min: 5
      consume-thread-max: 20
      pull-batch-size: 32
      max-reconsume-times: 3          # 最大重试3次,超过进入死信队列

max-reconsume-times配置建议:

业务类型 重试次数 原因
非核心业务 3次 快速失败,避免阻塞
核心业务(如支付) 5次 给依赖服务更多的恢复时间
避免使用默认值 默认16次 会导致消息长时间阻塞

6.3 死信消费者独立部署

关键规则 :死信队列的消费者组必须独立于原消费者组,否则无法消费DLQ中的消息。

java 复制代码
@Component
@RocketMQMessageListener(
        topic = "%DLQ%order-consumer-group",   // 死信队列Topic
        consumerGroup = "dlq-handler-group"     // 独立的消费者组
)
public class DlqHandlerConsumer implements RocketMQListener<String> {

    @Autowired
    private AlertService alertService;

    @Override
    public void onMessage(String message) {
        log.error("收到死信消息,需要人工介入: {}", message);

        // 策略一:自动补偿(需保证幂等)
        try {
            compensateService.retry(message);
        } catch (Exception e) {
            // 策略二:补偿失败,发送告警
            alertService.sendAlert("死信消息补偿失败", message);
        }
    }
}

死信消息的处理策略:优先选择"自动补偿(幂等)+ 人工介入兜底"的组合策略,并配置监控告警避免消息堆积。

6.4 死信队列监控

java 复制代码
@Component
@Slf4j
public class DlqMonitor {

    @Autowired
    private AlertService alertService;

    @Scheduled(fixedDelay = 60000)  // 每分钟检查一次
    public void checkDlqSize() {
        // 通过 RocketMQ 管理API 查询死信队列的消息数
        long dlqSize = rocketMQAdmin.getDlqMessageCount("order-consumer-group");
        if (dlqSize > 100) {
            alertService.sendAlert("死信队列堆积告警", "当前死信消息数: " + dlqSize);
        }
    }
}

七、RabbitMQ与RocketMQ选型对比

7.1 核心差异对照

维度 RocketMQ RabbitMQ Kafka
语言 Java Erlang Scala/Java
单机吞吐量 10万+ TPS 万级 TPS 10万+ TPS
延迟 <1ms 微秒级 2-5ms
事务消息 ✅ 完整支持 ❌ 需自己实现 ❌ 有限支持
顺序消息 ✅ 分区有序 ❌ ✅ 分区有序
延迟消息 ✅ 任意精度 需插件 ❌
路由灵活性 中等 ✅ 极强 弱
运维复杂度 中等 低 高

7.2 选型决策框架

场景 推荐 原因
分布式事务(订单→库存) RocketMQ 原生事务消息支持
延迟消息(支付超时取消) RocketMQ 任意时间精度
复杂路由(多条件分发) RabbitMQ 交换机类型丰富
中小规模业务解耦 RabbitMQ 轻量、易运维
大数据流处理 Kafka 高吞吐、持久化日志

本专栏选型 :使用RocketMQ作为消息驱动的主力方案,原因是它在事务消息、延迟消息、顺序消息三个维度上的原生支持,完美覆盖了微服务场景的核心需求。

八、生产环境关键配置与踩坑指南

8.1 消费者端可靠消费配置

yaml 复制代码
spring:
  rocketmq:
    consumer:
      group: order-consumer-group
      consume-mode: CLUSTERING          # 集群消费
      consume-thread-min: 10            # 最小消费线程
      consume-thread-max: 50            # 最大消费线程
      pull-batch-size: 32               # 批量拉取条数
      max-reconsume-times: 3            # 最大重试次数
      consume-timeout: 15               # 消费超时(分钟)
      suspend-current-queue-millis: 2000  # 消费失败后暂停拉取时间

核心参数解读:

参数 作用 建议值
consume-thread-min/max 消费线程池大小 根据消费耗时调整
pull-batch-size 每次拉取的消息条数 32~64
max-reconsume-times 进入死信队列前的重试次数 3~5
consume-timeout 消息消费超时时间 15分钟

8.2 踩坑指南

坑一:消费线程池被打满。 现象:消息堆积但消费者不消费。原因:某条消息的消费逻辑中执行了耗时操作(如HTTP调用),占满了消费线程。解决:将耗时操作异步化(第29课的@Async),或增加消费线程数。

坑二:死信队列无人处理。 现象:死信队列消息数持续增长,无人感知。原因:未配置死信队列监控和告警。解决:配置定期检查死信队列大小的定时任务,超过阈值触发告警。

坑三:消息顺序错乱。 现象:订单状态流转出现"已支付→待支付"的逆序。原因:使用了并发消费(ConsumeMode.CONCURRENTLY),但业务需要顺序保证。解决:对于需要顺序的场景,使用ConsumeMode.ORDERLY,并确保生产端将同一业务Key的消息发送到同一个队列。

坑四:Spring Cloud Stream绑定不生效。 现象:消息发送成功但消费者未收到。原因:spring.cloud.stream.bindings.<binding-name>.destination与@RocketMQMessageListener的topic配置不一致。解决:确保两者使用相同的Topic名称。

坑五:事务消息回查失败。 现象:事务消息长期处于"半事务消息"状态,最终被强制回滚。原因:checkLocalTransaction方法未正确实现,或本地事务状态未持久化。解决:确保回查方法能通过唯一业务Key(如订单号)查到本地事务的最终状态。

坑六:消息体过大导致发送失败。 现象:发送大消息时报MQClientException: message body size exceeded。原因:RocketMQ默认单条消息最大4MB。解决:大消息存储到OSS/S3,消息体中只携带文件的URL。

九、课后作业

作业一 :部署RocketMQ 5.3.1(NameServer + Broker + Proxy),在service-order中配置Spring Cloud Stream的RocketMQ Binder,实现订单创建消息的发送。在service-product中实现消费者,验证消息接收成功。

作业二 :实现RocketMQ事务消息。在service-order中配置TransactionMQProducer和TransactionListener,验证:本地事务成功时消息被投递,本地事务失败时消息被回滚。

作业三 :在OrderCreatedConsumer中实现基于Redis SETNX的幂等校验。模拟消息重复投递(通过手动重发消息),验证第二次消费被幂等拦截。

作业四 :配置死信队列。将max-reconsume-times设为3,在消费者中人为抛出异常。验证:消息重试3次后进入%DLQ%order-consumer-group,创建独立的死信消费者组并消费该消息。

作业五(进阶) :对比RabbitMQ和RocketMQ在相同业务场景(订单通知)下的开发体验和性能表现。使用JMeter压测两种方案的消息发送吞吐量和消费延迟,记录对比数据。

十、阶段总结与下节预告

至此,微服务高阶特性 & 分布式核心能力阶段(第29-31课) 全部完成:

课程 核心能力 关键产出
第29课 异步调用与事件驱动 @Async、线程池调优、Spring事件
第30课 分布式事务与Seata AT模式、全局锁、@GlobalTransactional
第31课 消息驱动与解耦 事务消息、消费幂等、死信队列

三课串联的核心逻辑 :第29课解决了单服务内的异步与解耦 ,第30课解决了跨服务的强一致性 ,第31课解决了跨服务的最终一致性与异步解耦。三者构成了微服务数据一致性的完整方案体系:Spring事件处理模块解耦,Seata处理强一致场景,RocketMQ处理最终一致场景。

第32课将进入企业级完整项目实战 & 架构复盘阶段 ------企业级微服务项目架构设计 & 全模块搭建。我们将基于前31课的所有技术栈,从零搭建一个完整的电商微服务项目(用户服务、订单服务、商品服务、支付服务、网关服务),完成业务拆分设计、领域驱动简易落地、统一返回体、统一异常处理和完整项目初始化。前31课是"造零件",第32课是"组装整车"。

🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航

去订阅

第一部分:微服务前置基础 & 新版环境搭建(第1-5课)

第二部分:注册中心核心(Nacos 最新版)(第6-9课)

第三部分:配置中心核心(Nacos配置中心)(第10-12课)

第四部分:服务通信核心(OpenFeign + LoadBalancer)(第13-16课)

第五部分:网关核心(SpringCloud Gateway 新版)(第17-20课)

第六部分:熔断、限流、降级(Sentinel 新版)(第21-24课)

第七部分:微服务监控、链路追踪、日志体系(第25-28课)

第八部分:微服务高阶特性 & 分布式核心能力(第29-31课)

第九部分:企业级完整项目实战 & 架构复盘(第32-35课)

相关推荐
蓝胖的四次元口袋2 小时前
RabbitMQ知识梳理(1)
分布式·rabbitmq
Knight_AL14 小时前
本地服务连接 SaaS 测试环境实践:Docker 部署 Redis 与 RocketMQ 完成接口联调
redis·docker·rocketmq
jyOverQ20 小时前
从零开始学 RocketMQ(一):基础概念、环境搭建与简单消息收发【保姆级教程】
java·rocketmq·java-rocketmq
Thomas.Sir1 天前
第29课:微服务异步调用、线程池优化 & 事件驱动开发
java·redis·微服务
CarIise1 天前
Maven私服(Nexus)
微服务
敲上瘾1 天前
分布式系统——Redis哨兵:自动故障转移与选举原理
linux·数据库·redis·分布式·缓存·微服务
旋生万物2 天前
分形自相似:微服务、缓存、Prompt 模板为什么长一样
人工智能·缓存·微服务·云原生·prompt
Thomas.Sir2 天前
第27课:SkyWalking全链路追踪实战 & 微服务调用链路分析
spring cloud·微服务·skywalking
做个文艺程序员2 天前
MQ第10篇:RAG与消息队列实战:Java构建AI客服系统的检索增强生成完整架构
人工智能·架构·rocketmq·向量数据库·rag·ai客服·spring ai