Malize's blog Malize's blog
首页
  • 设计模式

    • 设计模式总览
    • 工作中用到的设计模式
  • 并发编程

    • 死锁
  • 技术文档

    • Docker 核心命令大全
    • Markdown 使用教程
    • npm 常用命令
    • yaml 语言教程
    • Nodejs 递归读文件
  • DDD 领域驱动(基础)

    • DDD 是什么
    • 领域、子域与限界上下文
    • 实体、值对象与聚合
    • 领域事件
    • 分层架构与架构模型
  • DDD 领域驱动(实战)

    • DDD、中台与微服务
    • 事件风暴与中台建模
    • 微服务代码模型
    • 边界、视图与微前端
    • 设计实例与拆分原则
    • 分布式架构关键设计10问
  • 学习笔记总览
  • 入门
  • 部署
  • 进阶
  • 集成
  • 优化
  • 面试
  • 构造问答系统

    • 项目背景
    • 构建答疑机器人
    • 扩展知识范围
    • 优化提示词
    • 自动化评测
    • 优化 RAG 应用
  • 构建 Agent 系统

    • Agent 基础与工具调用
    • 规划与执行
    • 多 Agent 团队协作
    • Memory 积累经验
    • Skill 可复用流程
    • Qwen Code 实践
  • 交付上线

    • 走向生产环境
    • 模型蒸馏
    • 部署模型
    • 生产实践
    • 安全合规
  • 工具手册

    • OpenClaw 命令速查
  • 规范 & 实践

    • 代码规范
    • sharding-jdbc
    • CIM 半导体行业
    • HTML 常用 meta
    • CSS 技巧收藏
  • 微服务

    • feign原理
  • Git

    • Git 笔记总览
    • Git 使用手册
    • Git 修改分支名
    • 团队 Git 分支规范
  • GitHub & 博客

    • GitHub 高级搜索技巧
    • GitHub Actions 自动部署
    • 博客搭建 - 百度收录
  • 优质网站
  • 前端库推荐
  • 成长学习

    • 学习方法
    • 英语学习:奥格登 850 词
    • 敏捷开发实战
    • 提示词工程
  • 生活

    • 实用技巧
    • 心情杂货
    • 梦境与灵感
  • 技术问题

    • 面试问题备忘
  • 索引

    • 分类
    • 标签
    • 按年归档
GitHub (opens new window)

Malize

持续学习,持续成长
首页
  • 设计模式

    • 设计模式总览
    • 工作中用到的设计模式
  • 并发编程

    • 死锁
  • 技术文档

    • Docker 核心命令大全
    • Markdown 使用教程
    • npm 常用命令
    • yaml 语言教程
    • Nodejs 递归读文件
  • DDD 领域驱动(基础)

    • DDD 是什么
    • 领域、子域与限界上下文
    • 实体、值对象与聚合
    • 领域事件
    • 分层架构与架构模型
  • DDD 领域驱动(实战)

    • DDD、中台与微服务
    • 事件风暴与中台建模
    • 微服务代码模型
    • 边界、视图与微前端
    • 设计实例与拆分原则
    • 分布式架构关键设计10问
  • 学习笔记总览
  • 入门
  • 部署
  • 进阶
  • 集成
  • 优化
  • 面试
  • 构造问答系统

    • 项目背景
    • 构建答疑机器人
    • 扩展知识范围
    • 优化提示词
    • 自动化评测
    • 优化 RAG 应用
  • 构建 Agent 系统

    • Agent 基础与工具调用
    • 规划与执行
    • 多 Agent 团队协作
    • Memory 积累经验
    • Skill 可复用流程
    • Qwen Code 实践
  • 交付上线

    • 走向生产环境
    • 模型蒸馏
    • 部署模型
    • 生产实践
    • 安全合规
  • 工具手册

    • OpenClaw 命令速查
  • 规范 & 实践

    • 代码规范
    • sharding-jdbc
    • CIM 半导体行业
    • HTML 常用 meta
    • CSS 技巧收藏
  • 微服务

    • feign原理
  • Git

    • Git 笔记总览
    • Git 使用手册
    • Git 修改分支名
    • 团队 Git 分支规范
  • GitHub & 博客

    • GitHub 高级搜索技巧
    • GitHub Actions 自动部署
    • 博客搭建 - 百度收录
  • 优质网站
  • 前端库推荐
  • 成长学习

    • 学习方法
    • 英语学习:奥格登 850 词
    • 敏捷开发实战
    • 提示词工程
  • 生活

    • 实用技巧
    • 心情杂货
    • 梦境与灵感
  • 技术问题

    • 面试问题备忘
  • 索引

    • 分类
    • 标签
    • 按年归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

  • 博客搭建

  • CIM

  • 代码规范

  • 前端基础

  • 微服务

  • Git

  • 数据库

  • DDD领域驱动

    • DDD是什么:为什么微服务设计要选择DDD
    • 领域、子域与限界上下文
    • 实体、值对象、聚合与聚合根
    • 领域事件:微服务解耦的关键
      • 一、什么是领域事件
      • 二、为什么用事件而不是直接调用
      • 三、两种场景,处理方式不同
        • 微服务内(聚合之间)
        • 微服务之间(重点场景)
      • 四、一个完整案例:保险承保流程
      • 五、落地的技术要点
        • 1. 事件实体怎么设计
        • 2. 事件数据要持久化
        • 3. 完整运行链路(以"缴费通知单已生成"为例)
      • 六、小结
    • DDD分层架构与微服务架构模型
    • DDD、中台与微服务的铁三角
    • 事件风暴与中台业务建模实战
    • DDD微服务代码模型设计
    • 微服务的边界、数据视图与微前端
    • 微服务设计实例与拆分原则
    • 分布式架构关键设计10问
  • Elasticsearch

  • 技术
  • DDD领域驱动
malize
2026-08-03
目录

领域事件:微服务解耦的关键

# 领域事件:微服务解耦的关键

领域事件(Domain Event)是我认为 DDD 里最实用的概念之一——即使不搞完整的 DDD,事件驱动的解耦思路也值得每个做微服务的人掌握。

# 一、什么是领域事件

一句话:领域中发生的、会引发后续业务动作的事情。

怎么在需求分析时识别它?听关键句式——业务人员嘴里出现这些话时,八成就是领域事件:

  • "如果发生……,则……"
  • "当做完……的时候,请通知……"

几个典型例子:

  • 缴费完成后 → 触发投保单转保单
  • 密码连续输错三次 → 触发账户锁定
  • 定时批处理生成缴费通知单 → 触发邮件通知

# 二、为什么用事件而不是直接调用

回顾聚合设计原则里的一条:一次事务只改一个聚合,跨聚合用最终一致性。

直接服务调用(传统 SOA 风格)的问题:

  • 调用方必须知道被调方,强依赖
  • 跨服务改数据要上分布式事务,性能差、耦合重
  • 一个发布方对接 N 个下游时,调用关系爆炸

事件驱动则是"我干完了我的事,广播一声,谁关心谁处理":

  • 发布方不关心订阅方是否处理成功,彻底解耦
  • 天然支持一个发布方、N 个订阅方——这是直接调用做不到的
  • 用最终一致性替代分布式事务,性能好得多

# 三、两种场景,处理方式不同

# 微服务内(聚合之间)

同一个进程里,事务好控制,不一定需要消息中间件,用进程内事件总线(EventBus)即可。但要不要引入事件总线,得权衡开发复杂度和收益——简单场景直接在应用层做服务编排也行(代价是可能引入分布式事务)。

# 微服务之间(重点场景)

跨服务的事件要考虑一整套机制:事件构建 → 持久化 → 发布到消息中间件(Kafka/RabbitMQ)→ 订阅方接收 → 落库 → 处理。

# 四、一个完整案例:保险承保流程

看事件怎么驱动业务在多个微服务之间流转:

投保微服务:生成缴费通知单
    │ 事件①「缴费通知单已生成」→ MQ
    ▼
收款微服务:订阅事件,完成缴费
    │ 事件②「缴费已完成」→ MQ        ← 注意:订阅方变成了发布方
    ▼
投保微服务:确认缴费,投保单转保单
    │ 事件③「保单已生成」→ MQ
    ▼
保单微服务:保存保单
    │ 后续事件并发广播 → 佣金 / 收付费 / 再保 / 财务微服务
1
2
3
4
5
6
7
8
9
10
11

整条业务链没有一次同步的跨服务调用,全靠事件推着走。任何一个下游挂了,事件还在 MQ 里,恢复后继续消费,业务闭环不断。

# 五、落地的技术要点

# 1. 事件实体怎么设计

事件至少包含两类数据:

  • 基本属性:全局唯一的事件 ID、发生时间、事件类型、事件源
  • 业务属性:事件发生那一刻的业务数据快照——事件一旦发生就不可变,所以业务数据适合用序列化值对象保存

实践中会定义一个 DomainEvent 基类统一事件结构,子类按需扩展。

# 2. 事件数据要持久化

持久化的目的:对账、审计,以及 MQ 或订阅方宕机后能恢复业务。两种方案:

方案 优点 缺点
存本地业务库的事件表 本地事务就能保证业务+事件一致 事件数据分散
存共享事件库 集中管理 跨库要分布式事务,伤性能

推荐第一种——业务数据和事件数据在同一个本地事务里落库,然后由定时任务或数据库日志捕获(CDC)把增量事件发到 MQ。这其实就是常说的 Transactional Outbox 模式,避免了"业务落库成功但消息发送失败"的经典难题。

# 3. 完整运行链路(以"缴费通知单已生成"为例)

  1. 投保微服务的应用服务调用领域服务,创建缴费通知单 + 事件实体
  2. 仓储将业务数据和事件数据持久化到本地库(同一个本地事务,无分布式事务)
  3. 定时程序或 CDC 从事件表捞增量,发布到消息中间件
  4. 收款微服务监听 MQ,拿到事件数据先落本地库
  5. 调用领域服务完成缴费,事件结束

# 六、小结

  • 领域事件 = "发生了某事,需要有后续动作",识别靠听业务人员的"如果……则……"
  • 核心价值:切断服务间强依赖,用最终一致性替代分布式事务
  • 微服务内用事件总线(可选),微服务间用消息中间件(常态)
  • 事件数据先落本地库再异步发 MQ,是保证可靠性的关键一招

结合之前整理的 Kafka 面试题汇总,领域事件就是 MQ 在业务架构层面的"正确打开方式"。

编辑 (opens new window)
#DDD#微服务#消息队列
上次更新: 2026/10/08, 03:22:29
实体、值对象、聚合与聚合根
DDD分层架构与微服务架构模型

← 实体、值对象、聚合与聚合根 DDD分层架构与微服务架构模型→

最近更新
01
奥格登基础英语 850 词
10-08
02
Elasticsearch 入门
10-08
03
Elasticsearch 优化
10-08
更多文章>
Theme by Vdoing | Copyright © 2023-2026 Malize | GitHub | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式