2. Azure事件网格核心模型

Azure 事件网格(Azure Event Grid)是一套完全托管的发布/订阅事件路由服务。理解它的关键,不是记住某个 API,而是先建立一张清晰的“事件流转地图”:事件从哪里产生、经过哪个入口进入事件网格、被哪些订阅筛选、最终投递到哪些处理程序。围绕这张地图,事件网格把核心对象抽象为五类:事件源(Event Source)、主题(Topic)、事件订阅(Event Subscription)、事件处理程序(Event Handler),以及主题的两种形态——系统主题(System Topic)与自定义主题(Custom Topic)。

一、事件源:事件的产生者

事件源是“谁发生了事情”。在 Azure 中,事件源可以是 Blob 存储、资源组、订阅、容器注册表、IoT 中心、服务总线、Key Vault、App Configuration 等 Azure 服务,也可以是你自己编写的应用程序。事件源产生的数据称为事件(Event),它描述“发生了什么”,而不是“要做什么”。例如,Blob 创建事件只说明某个容器里新增了一个文件,并不关心谁去处理它。

事件源分为两类:一类是 Azure 服务,它们天然支持向事件网格推送事件;另一类是自定义应用,需要通过 HTTP POST 把事件发送到自定义主题。理解这一点很重要,因为它决定了你后续是使用系统主题还是自定义主题。

二、主题:事件的入口与容器

主题是事件网格中接收事件的端点,可以理解为“事件的收件箱”。事件源把事件发布到主题,订阅再从主题中获取事件。主题本身不存储事件,它只负责接收并立即路由。事件网格提供两种主题:

  • 系统主题(System Topic):由 Azure 服务自动创建和管理,用于接收某个 Azure 资源产生的事件。例如,为某个存储账户创建系统主题后,该账户的 Blob 事件就会进入这个主题。系统主题与资源绑定,生命周期通常跟随资源。
  • 自定义主题(Custom Topic):由用户手动创建,用于接收自定义应用发布的事件。它提供一个 HTTPS 端点,应用通过 POST 请求把事件发送到该端点。自定义主题适合跨服务、跨订阅的事件集成场景。

两者的核心区别在于“谁产生事件”和“谁管理主题”。系统主题面向 Azure 服务事件,管理成本低;自定义主题面向应用事件,灵活度高。选择时先问:事件来自 Azure 服务还是我的代码?前者用系统主题,后者用自定义主题。

三、事件订阅:筛选与路由规则

事件订阅是连接主题与处理程序的“管道”,它定义了“哪些事件”以及“送到哪里”。一个主题可以有多个订阅,每个订阅独立筛选、独立投递。事件订阅包含三个关键要素:

  1. 事件类型筛选:例如只订阅 Microsoft.Storage.BlobCreated,忽略删除事件。
  2. 主题筛选(Subject Filter):按事件主题字段做前缀或后缀匹配,例如只处理 /blobServices/default/containers/images/ 下的事件。
  3. 高级筛选:基于事件属性做数值比较、布尔判断或字符串包含,例如只处理 data.api 为 PutBlock 的事件。

订阅还定义了投递方式:推送到 Webhook、Azure 函数、服务总线队列、事件中心、存储队列等。投递失败时,事件网格支持重试策略和死信(Dead Letter)存储,避免事件丢失。

四、事件处理程序:事件的消费者

事件处理程序是“谁来处理事件”。常见类型包括 Azure Functions、Webhook、服务总线队列/主题、事件中心、存储队列、逻辑应用等。处理程序不关心事件从哪来,只关心收到的事件内容。事件网格以 HTTP POST 方式把事件推送给处理程序,处理程序返回 2xx 表示成功,否则触发重试。

一个典型模式是:Blob 创建事件 → 系统主题 → 事件订阅(筛选 images 容器)→ Azure 函数生成缩略图。这里 Blob 是事件源,系统主题是入口,订阅负责筛选,函数是处理程序。

五、核心模型关系图

下图把事件源、主题、订阅、处理程序以及系统主题/自定义主题的关系放在同一张图中,帮助建立整体认知。

Azure 事件网格核心模型 事件源 Blob 存储 资源组 / 订阅 IoT 中心 / Key Vault 自定义应用 主题(Topic) 系统主题 Azure 服务事件 · 自动管理 自定义主题 应用事件 · HTTPS 端点 事件订阅 事件类型筛选 主题筛选 高级筛选 重试 / 死信 事件处理程序 Azure Functions Webhook / 逻辑应用 服务总线 / 事件中心 / 存储队列 返回 2xx 表示成功,否则重试 发布事件 路由 推送事件 选择要点 Azure 服务事件 → 系统主题 应用事件 → 自定义主题 一个主题可挂多个订阅 订阅独立筛选、独立投递

六、系统主题与自定义主题的实践选择

在实际工程中,选择系统主题还是自定义主题,通常由事件来源决定。假设你要在存储账户 stcontoso01 中监听 images 容器的 Blob 创建事件,并触发函数生成缩略图。此时事件源是 Azure 存储,应创建系统主题,再创建事件订阅,筛选条件如下:

事件类型:Microsoft.Storage.BlobCreated
主题筛选:/blobServices/default/containers/images/
处理程序:Azure Function(缩略图生成)
重试策略:默认 24 小时,最多 30 次
死信:启用,指向存储队列

如果事件来自你自己的订单服务,例如订单创建后需要通知库存、通知和审计三个下游系统,则应创建自定义主题,由订单服务向该主题的 HTTPS 端点 POST 事件,然后为库存、通知、审计分别创建三个事件订阅。这样每个下游系统只收到自己关心的事件,互不影响。

系统主题与自定义主题并不是互斥的。一个应用可以同时使用系统主题接收 Azure 服务事件,使用自定义主题接收自身业务事件,再通过统一的处理程序或事件中心做汇聚。

七、常见误区与判断依据

第一个误区是把主题当成消息队列。事件网格主题不存储事件,事件到达后立即路由;如果需要缓冲和持久化,应使用服务总线或存储队列作为处理程序。第二个误区是认为一个订阅可以同时处理所有事件。实际上,订阅是筛选和路由的最小单元,不同处理逻辑应拆成不同订阅。第三个误区是忽略死信。当处理程序长时间不可用时,事件会被重试直到过期,启用死信可以把失败事件保存下来,便于后续排查和补偿。

判断模型是否正确的简单方法是:沿着“事件源 → 主题 → 订阅 → 处理程序”走一遍,确认每个环节都有明确的对象和配置。如果某个环节缺失,事件就无法到达终点;如果订阅筛选过宽,处理程序会收到无关事件;如果筛选过窄,关键事件会被静默丢弃。掌握这五个核心对象及其关系,就掌握了 Azure 事件网格的骨架。