事件架构体系完整梳理

一、宏观核心理念

所有事件架构底层统一范式:发布-订阅模式
核心思想:事件生产者只负责产生事件,不关心消费方是谁、如何消费;消费方只关注自身订阅的事件,不感知事件来源,以此实现业务解耦、流程异步、系统横向扩展。

依据事件流转载体、通信边界,划分为两大独立谱系,理念同源但运行环境、能力边界完全隔离,工程中常嵌套组合,不可互相替代:

  1. 内存事件体系(进程内事件):事件对象驻留进程内存,无网络交互,作用域仅限单进程;
  2. 网络事件体系(分布式事件):事件依托网络传输,跨进程、跨主机、跨系统,支持外部客户端接入。

重要前置说明:
高层框架(SpringEvent、WebSocket、gRPC)本质是底层通信模型的封装;底层裸TCP/UDP、自定义私有协议、RPC、DDE等是原始实现形态。高层方案降低开发成本,底层方案追求极致可控、性能。

二、通用四层标准分层架构(所有事件模型通用骨架)

  1. 事件生产层:业务动作触发事件(数据变更、状态告警、流程完成);
  2. 事件调度层(核心中枢):维护订阅关系、执行事件过滤、匹配目标消费主体;
  3. 事件传输层:事件承载与流转通道,区分内存/网络两大体系的核心层
  4. 事件消费层:接收并处理事件的主体(进程内模块 / 外部客户端程序)。

三、第一大体系:内存事件架构(进程内本地事件)

3.1 定位

解决单一进程内部模块耦合,不需要跨进程、不需要网络,作为服务内部代码解耦工具。

3.2 通用运行链路

业务代码产生事件 → 发布事件对象至内存总线 → 总线检索已注册订阅者 → 同步/异步调用订阅处理器执行逻辑

3.3 典型实现范例 & 简要结构说明

范例1:C# 原生 event / 委托

  • 实现结构:内部维护 Delegate 委托链表;发布者触发委托执行所有订阅方法;
  • 特点:最轻量化原生实现,无第三方依赖;需要开发者自行处理内存泄漏(弱引用优化);
  • 适用:Windows桌面程序、后端服务内部模块通知。

范例2:Spring ApplicationEvent / Guava EventBus(Java)

  • 实现结构:框架内置事件注册表,区分同步/异步调度;事件为普通Java对象;
  • 特点:开箱即用,统一异常处理;仅进程内有效。

范例3:MediatR(.NET生态内存总线)

  • 实现结构:中介者模式封装,统一消息分发接口,隔离发布者与处理器;
  • 特点:标准化消息模型,便于后续切换为分布式消息。

范例4:Windows DDE(动态数据交换,跨进程古老内存/IPC机制补充

注意:严格来说DDE属于IPC进程间通信,不属于纯内存进程内事件,常容易混淆,在此区分说明

  • 结构:DDE服务端注册主题名称;客户端订阅Topic;进程间通过操作系统内核缓冲区交换消息;
  • 底层:操作系统提供的IPC机制,并非单进程内存;老旧Office软件、工控上位机历史方案;
  • 局限:协议老旧、性能差、仅Windows平台,新项目基本淘汰。

拓展同类IPC参考(容易和内存事件混淆)

Windows:WM_COPYDATA、命名管道;Linux:信号、匿名管道、Unix域套接字。

分界线:纯内存事件 = 同一个进程地址空间;IPC = 跨进程,依靠操作系统中转,不属于内存事件体系

3.4 核心特性

✅ 优势:无序列化、无网络IO,性能极高;零中间件依赖
❌ 约束:进程崩溃事件全部丢失;不支持跨进程;无持久化、无重试

3.5 两种执行模式

  1. 同步事件:发布线程串行执行监听,阻塞主业务;
  2. 异步事件:线程池调度监听逻辑,解除主流程阻塞。

四、第二大体系:网络事件架构(分布式对外事件)

定位:事件需要跨进程、跨服务器,推送至外部客户端(浏览器、桌面程序、硬件设备、第三方服务)。
架构形态区分:单机直连模式;集群模式(引入MQ实现事件削峰、生产者与推送服务解耦)。

完整集群标准链路:
业务产生事件 → 可选【内存事件总线内部解耦】 → 消息投递MQ → 路由服务消费事件 → 订阅规则匹配目标客户端 → 通过网络通道完成交付

4.1 分类一:客户端主动拉取(服务端被动应答)

1)短轮询(HTTP)

  • 机制:客户端周期性发起HTTP请求,服务端查询消息立刻返回,连接随即关闭;
  • 示例:后台页面3秒刷新一次任务状态接口。

2)长轮询 Long Polling(HTTP)

  • 机制:请求到达后若无消息则挂起连接;消息到达或超时后返回;客户端收到响应立刻重发;
  • 实现要点:集群场景消息缓冲必须使用Redis,禁止进程内存缓存;
  • 示例:部分物联网平台第三方设备对接、老旧防火墙环境下的消息通知。

3)SSE

  • 机制:单向HTTP流式长连接,仅服务端向客户端下发数据,客户端无法上行;
  • 示例:运维监控大屏实时指标展示。

4.2 分类二:服务端主动推送模式(客户端仅负责建立连接,服务端随时下发事件)

由底层到高层依次罗列,补充裸TCP/UDP、自定义私有协议、RPC、WebSocket完整谱系

范例1:裸 TCP + 自定义私有二进制协议(底层长连接方案)

结构实现简述

  1. 客户端主动Connect TCP服务端,完成握手、身份认证、上报订阅规则;
  2. 服务端内存维护:Socket连接 <-> 客户端标识 <-> 订阅规则;
  3. 事件匹配成功后,按照自定义协议封装二进制数据包,通过已有TCP连接主动send下发;
  4. 自定义协议包含:消息长度、消息类型、MsgId、载荷、校验码;
  5. 依靠心跳包检测断线,及时清理无效连接。
  • 特点:自由度最高;TCP可靠有序;需要自行处理粘包、分包、断线重连、序列化;
  • 典型场景:工控设备、物联网终端、游戏服务端推送。

范例2:UDP + 自定义协议(无连接推送)

结构实现简述

  1. 客户端启动后定期向服务端上报自身地址、订阅信息;服务端记录客户端IP+端口;
  2. 事件产生并匹配客户端后,直接通过UDP报文推送事件;
  3. 上层自行实现序号、重传机制弥补UDP不可靠缺陷。
  • 特点:无连接、开销极低;不保证送达、乱序;适合对实时性要求极高、允许少量丢包场景;
  • 示例:局域网实时音视频状态广播、局域网设备发现、游戏状态同步。

范例3:RPC框架推送模式(gRPC Stream / Dubbo Stream)

结构实现简述
基于TCP底层,框架封装通信、序列化;依靠双向流Stream实现长连接:

  1. 客户端调用RPC流式接口,建立双向流通道;
  2. 服务端持有Stream句柄,事件匹配完成后,主动通过Stream推送消息;
  • 本质:封装后的TCP长连接;自带序列化、超时、负载均衡;
  • 示例:微服务之间实时指令推送、云平台终端控制。

范例4:WebSocket(HTTP协议升级后的长连接)

结构实现简述
握手阶段使用HTTP,随后升级为持久双向长连接;底层依然基于TCP;
服务端维护连接池与订阅关系,事件匹配后主动推送文本/二进制消息;

  • 特点:浏览器原生支持;防火墙友好度优于裸TCP;
  • 示例:Web聊天、前端实时告警通知。

4.3 网络事件通用设计准则

  1. 路由匹配逻辑与传输通道解耦:同一套订阅过滤规则,可以同时对接TCP私有协议、WebSocket、长轮询;
  2. MQ只负责消息中转,复杂权限、多条件订阅过滤放在路由服务,不要下沉至MQ Topic;
  3. 匹配优化:建立「事件类型 → 订阅客户端集合」索引,禁止事件到达后遍历全部客户端;
  4. 离线策略统一:在线即时推送;离线可选择丢弃 / 缓冲区暂存、上线补发,设置消息过期时间与缓冲上限。

五、工程标准组合方案(内存事件 + 网络事件协同)

真实项目中两套体系经常嵌套使用,形成标准链路:
业务操作 → 发布进程内内存事件
├─ 本地监听器:缓存刷新、日志、统计等内部逻辑
└─ 转发监听器:序列化事件向外分发
▷ 单机部署:直接调用TCP/WebSocket路由模块,主动推送客户端
▷ 集群部署:消息投递MQ,由独立路由服务消费,通过各类网络通道推送

六、全局总结

  1. 思想统一:所有事件模型根基都是发布订阅;核心分水岭在于事件是否跨进程、是否依托网络传输,划分为内存事件体系、网络事件体系。
  2. 职责边界清晰
    • 内存事件体系:面向单进程内部代码解耦,轻量化高性能;代表:C# event、Spring Event;不要尝试用于跨进程通信;
    • 网络事件体系:面向跨主机、对外客户端分发;底层可选裸TCP/UDP自定义协议,中层RPC流式通信,高层WebSocket、HTTP轮询方案,可根据可控性、开发成本选型。
  3. 底层到高层选型参考
    • 需要极致可控、对接硬件设备 → 裸TCP/UDP自定义私有协议;
    • 微服务体系、不想手写底层通信 → gRPC Stream等RPC流;
    • Web前端接入 → WebSocket / 长轮询 / SSE;
  4. 最佳实践范式
    使用内存事件作为业务内部解耦胶水,网络事件承载跨系统、对外推送需求,二者组合,兼顾代码可维护性与分布式扩展能力。