news 2026/7/15 0:37:51

事件驱动架构EDA与事件中心完整知识梳理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
事件驱动架构EDA与事件中心完整知识梳理

事件驱动架构EDA与事件中心完整知识梳理


一、什么是"事件"

概念

事件(Event)是系统中发生的一个"事实"的描述。它表示"某件事已经发生了",而不是"请你做某件事"。

对比项命令(Command)事件(Event)
语义“请你做XX”“XX已经发生了”
方向发送方知道接收方发送方不关心谁订阅
耦合度强耦合松耦合
示例createOrder(orderDto)OrderCreatedEvent
时态祈使句/将来时过去时

事件的三要素

{"type":"order.created",// 事件类型:发生了什么"source":"order-service",// 事件来源:谁产生的"data":{"orderId":"123"},// 事件数据:具体内容"time":"2026-07-14T10:28:00Z"// 事件时间:什么时候发生的}

注:

博客:

https://blog.csdn.net/badao_liumang_qizhi

二、事件驱动架构(EDA)

核心模型

┌──────────┐ ┌──────────────┐ ┌──────────┐ │ 生产者 │ 发布事件 │ 事件中心 │ 推送事件 │ 消费者 │ │ Producer │ ────────→ │ Event Broker │ ────────→ │ Consumer │ └──────────┘ └──────────────┘ └──────────┘ │ │ 推送事件 ▼ ┌──────────┐ │ 消费者 B │ └──────────┘

与传统同步调用对比

同步调用(点对点)

a服务 ──HTTP POST──→ b服务 ←──Response────

问题:b 挂了,a 的业务也跟着失败。

事件驱动(发布/订阅)

a服务 ──发布事件──→ 事件中心 ──推送──→ b服务 ──推送──→ 监控服务 ──推送──→ 日志服务

优势:b挂了不影响 a;将来新增消费者无需改 a 代码。

适用场景

  • 系统间异步通知(不需要同步等待结果)
  • 一个事件需要通知多个下游系统
  • 生产者和消费者由不同团队维护
  • 需要解耦上下游系统的部署和发布周期

三、CloudEvents 规范

CloudEvents 是 CNCF(云原生计算基金会)定义的事件格式标准,目的是让不同系统产生的事件有统一的格式。

核心属性

属性含义示例
specversion规范版本1.0
type事件类型aaa.xxx
source事件来源/bbb-service
id事件唯一IDuuid
time事件产生时间2026-07-14T10:28:00Z
data事件负载(业务数据)JSON 对象

HTTP 协议绑定

CloudEvents 通过 HTTP Header 传递元信息:

POST /event-center/api/v3/eventTypes/aaa.xxx/send Content-Type: application/json Ce-Type: aaa.xxx Ce-Specversion: 1.0 Authorization: Bearer <token> { "fulfillmentCode": "xx.20260714.000005.xx", "event": "ttt", "eventDate": "2026-07-14 10:28:00", "systemName": "uuu" }

四、事件中心的角色

事件中心(Event Center/Event Broker)是事件流转的中间枢纽:

┌─────────────────────────────────────────────────────────┐ │ 事件中心 │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │ │ │ 事件接收 │ │ 事件路由 │ │ 事件投递 │ │ │ │ (Ingress) │→ │ (Routing) │→ │ (Delivery) │ │ │ └────────────┘ └────────────┘ └────────────────┘ │ │ │ │ 职责: │ │ 1. 接收生产者发布的事件 │ │ 2. 根据 eventType 路由到对应订阅者 │ │ 3. 可靠投递(重试、死信队列) │ │ 4. 认证鉴权 │ └─────────────────────────────────────────────────────────┘

与 MQ 的区别

对比项MQ(RabbitMQ/Kafka)事件中心
范围同一系统/团队内部跨系统/跨团队/跨公司
协议AMQP/Kafka协议HTTP(CloudEvents)
订阅方式消费者主动拉取事件中心主动推送(Webhook)
运维方自己运维平台方统一运维
格式自定义标准化(CloudEvents)

五、通用代码示例

1. 事件发布工具类

/** * 事件中心推送工具类. * 基于 CloudEvents 规范,通过 HTTP POST 推送事件到事件中心. */@Component@Slf4jpublicclassEventPublisher{@Value("${event-center.token}")privateStringtoken;privatefinalRestTemplaterestTemplate;publicEventPublisher(RestTemplaterestTemplate){this.restTemplate=restTemplate;}/** * 发布事件到事件中心. * * @param eventType 事件类型,如 "order.created" * @param url 事件中心接收地址 * @param payload 事件数据(JSON 字符串) * @return 推送结果 */publicEventResultpublish(StringeventType,Stringurl,Stringpayload){try{HttpHeadersheaders=newHttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);headers.set("Authorization",token);headers.set("Ce-Type",eventType);headers.set("Ce-Specversion","1.0");HttpEntity<String>request=newHttpEntity<>(payload,headers);ResponseEntity<String>response=restTemplate.postForEntity(url,request,String.class);log.info("事件发布成功, type={}, response={}",eventType,response.getBody());returnEventResult.success(response.getBody());}catch(Exceptione){log.warn("事件发布失败, type={}",eventType,e);returnEventResult.fail(e.getMessage());}}}

2. 本地消息表 + 可靠发布

/** * 可靠事件发布服务. * 先写本地消息表,事务提交后再触发实际推送. */@ServicepublicclassReliableEventPublisher{@ResourceprivateEventLogRepositoryeventLogRepository;@ResourceprivateEventMqSendereventMqSender;/** * 记录待发布事件(在业务事务内调用). */@TransactionalpublicvoidprepareEvent(StringeventType,Stringpayload,StringbizKey){// 1. 写入本地消息表EventLogeventLog=newEventLog();eventLog.setEventType(eventType);eventLog.setPayload(payload);eventLog.setBizKey(bizKey);eventLog.setStatus(0);// 待发送eventLog.setRetryCount(0);eventLogRepository.save(eventLog);// 2. 注册事务提交后的回调,发送 MQAfterTransactionActionCollectorcollector=newAfterTransactionActionCollector();TransactionSynchronizationManager.registerSynchronization(collector);collector.addCommitSyncAction(()->eventMqSender.send(eventLog.getId()));}}

3. MQ 消费者 + 实际推送

/** * 事件推送 MQ 消费者. * 消费本地消息表 ID,执行实际推送. */@Component@Slf4jpublicclassEventPublishConsumer{@ResourceprivateEventLogRepositoryeventLogRepository;@ResourceprivateEventPublishereventPublisher;@RabbitListener(queues="${event.publish.queue}")publicvoidconsume(IntegereventLogId){EventLogeventLog=eventLogRepository.findById(eventLogId).orElse(null);if(eventLog==null){return;}// 已成功的跳过if(eventLog.getStatus()==1){return;}// 推送事件中心Stringurl=resolveUrl(eventLog.getEventType());EventResultresult=eventPublisher.publish(eventLog.getEventType(),url,eventLog.getPayload());// 更新状态if(result.isSuccess()){eventLog.setStatus(1);eventLog.setResponse(result.getBody());}else{eventLog.setStatus(2);eventLog.setErrorMsg(result.getErrorMsg());}eventLog.setRetryCount(eventLog.getRetryCount()+1);eventLogRepository.save(eventLog);}}

4. 事务同步回调机制

/** * Spring 事务同步回调示例. * 确保 MQ 消息在事务提交后才发送. */publicclassTransactionCallbackDemo{publicvoidbusinessMethod(){// ... 业务逻辑,操作数据库 ...// 注册事务提交后的回调TransactionSynchronizationManager.registerSynchronization(newTransactionSynchronization(){@OverridepublicvoidafterCommit(){// 事务提交成功后执行mqSender.send(message);}});}}

5. 运维重推接口

/** * 运维重推接口. * 用于手动触发失败事件的重新发布. */@RestController@RequestMapping("/api/inner/event")publicclassEventRetryController{@ResourceprivateEventMqSendereventMqSender;@ResourceprivateEventLogRepositoryeventLogRepository;@PostMapping("/retry")publicResult<Boolean>retry(@RequestBodyList<Integer>logIds){if(logIds==null||logIds.isEmpty()){// 未指定ID则查询所有失败记录List<EventLog>failedLogs=eventLogRepository.findByStatusInAndRetryCountLessThan(Arrays.asList(0,2),6);logIds=failedLogs.stream().map(EventLog::getId).collect(Collectors.toList());}logIds.forEach(eventMqSender::send);returnResult.success(true);}}

六、完整数据流示意

┌─ 你的服务内部 ─────────────────────────────┐ │ │ 业务代码 │ ① 写入本地消息表(status=0) │ │ │ ② 注册事务回调 │ ▼ │ │ │ 事务提交 ───────────│─────────┼────────────────────────────────────│ │ ▼ │ │ ③ 回调触发:发送 MQ(消息=logId) │ │ │ │ │ ▼ │ │ ④ MQ 消费者:读取消息表 → 组装 HTTP 请求 │ │ │ │ └─────────┼────────────────────────────────────┘ │ ▼ HTTP POST(CloudEvents 格式) ┌─────────────────────┐ │ 事件中心 │ │ 接收 → 路由 → 投递 │ └─────────┬───────────┘ │ Webhook 推送 ▼ ┌─────────────────────┐ │ b 服务 │ │ 接收事件 → 处理业务 │ └─────────────────────┘

七、核心概念速查表

概念一句话解释
事件(Event)已发生事实的描述,过去时
事件类型(Event Type)事件的分类标识,用于路由
事件中心(Event Broker)负责接收、路由、投递事件的中间平台
生产者(Producer)发布事件的服务
消费者(Consumer/Subscriber)订阅并处理事件的服务
CloudEventsCNCF 定义的事件格式标准
本地消息表(Outbox)确保事件可靠发布的数据库表
事务同步(Transaction Sync)确保消息在事务提交后才发送
最终一致性允许短暂不一致,但最终状态一致
幂等性同一事件重复投递不会产生副作用
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 0:22:14

为什么 AI 总是“一本正经地胡说八道”?大模型幻觉终于讲明白了

你问 AI&#xff1a;“这句话出自哪本书&#xff1f;”它给出书名、作者、出版社&#xff0c;甚至精确到页码。你满心欢喜地去查&#xff0c;却发现书里根本没有这句话。更令人困惑的是&#xff0c;它的语气没有一丝犹豫。这不是 AI 在故意撒谎&#xff0c;而是大模型最典型、也…

作者头像 李华
网站建设 2026/7/15 0:18:16

这个GitHub工具太狠了,一键把网站搬回家,断网照样用!

你有没有遇到过这种情况——在飞机上、地铁里&#xff0c;信号全无&#xff0c;想翻之前收藏的一个网页&#xff0c;死活打不开。这时候你就想&#xff0c;要是能把整个网站”搬”到本地该多好。还真有人做了这么个工具。叫 kage&#xff0c;一个越南老哥用 Go 写的。原理说起来…

作者头像 李华
网站建设 2026/7/14 23:59:46

M芯片Mac系统降级实战:从Ventura回退Monterey的完整避坑指南

1. 为什么M芯片Mac用户需要降级到Monterey&#xff1f; 去年刚拿到M2芯片的MacBook Pro时&#xff0c;我第一时间升级到了Ventura系统。结果第三天就遇到了微信闪退、Final Cut Pro渲染卡顿的问题。后来在开发者论坛发现&#xff0c;不少专业软件对Ventura的适配都存在问题。这…

作者头像 李华
网站建设 2026/7/14 23:55:40

Qt/C++开发实战资料:环境搭建、疑难排错与项目优化全攻略

1. 项目概述与资料价值解析最近在整理硬盘&#xff0c;翻出来一堆这些年做Qt/C项目时攒下的“家底”。从刚入门时四处搜罗的教程、源码&#xff0c;到后来项目实战中总结的笔记、踩坑记录&#xff0c;还有各种工具链的配置心得&#xff0c;零零总总快有几十个G了。想想这些资料…

作者头像 李华
网站建设 2026/7/14 23:54:38

NE4932B 5V 3.6A 输入两串锂电池升压充电芯片,耐压20V

NE4932B 5V 3.6A 输入两串锂电池升压充电芯片,耐压20VNE4932B 是一款支持双节串联锂电池/锂离子电池的升压充电管理IC。 内部集成功率 MOS&#xff0c;采用同步开关架构&#xff0c;使其在应用时仅需极少的外围器件&#xff0c;有效减小整体方案的尺寸&#xff0c;降低BOM 成本…

作者头像 李华
网站建设 2026/7/14 23:51:15

三大传参注解完整详解

一、RequestParam&#xff08;你项目绝大多数接口在用&#xff0c;form 表单 / URL 查询参数&#xff09;1. 接收数据来源两种数据载体&#xff1a;GET 请求&#xff1a;URL ? 后面拼接的键值对 例&#xff1a;/actionmall/product/findproducts.do?pageNum1&pageSize10P…

作者头像 李华