1. 事件驱动集成全景
在构建分布式系统时,集成方式决定了系统之间的耦合程度、响应能力和扩展边界。传统请求响应模式以调用方为主动方,被调用方被动等待;而事件驱动模式则把“发生了什么”作为一等公民,让生产者与消费者通过事件解耦。理解这两种范式的差异,是掌握 Azure 事件驱动集成工程的第一步。
请求响应与事件驱动的本质差异
请求响应模式的核心是同步调用:客户端发起 HTTP 请求,服务端处理并返回结果。调用方必须知道被调用方的地址、契约和可用性,并在等待期间保持连接。这种方式直观、易调试,但当调用链变长时,延迟会叠加,任一环节故障都会向上传播。例如订单服务同步调用库存服务、支付服务和通知服务,若支付服务响应缓慢,整个下单请求都会被拖住。
事件驱动模式则把交互拆成“发布事件”和“订阅事件”两个独立动作。订单服务在完成本地事务后,向事件通道发布一条 OrderPlaced 事件,随后立即返回。库存服务、支付服务和通知服务各自订阅该事件,独立处理。生产者不需要知道消费者是谁、有多少个、是否在线;消费者也不需要阻塞生产者。这种异步、松耦合的结构带来了更好的弹性,但也引入了最终一致性、重复投递和顺序问题。
需要强调的是,事件驱动不是对请求响应的替代,而是补充。查询类、需要即时确认的操作仍适合请求响应;而状态变更通知、跨服务数据同步、异步任务触发则更适合事件驱动。工程上常见的做法是“命令走请求响应,事实走事件”。
Azure 集成服务矩阵
Azure 提供了一组互补的集成服务,选择哪一种取决于消息语义、吞吐量、顺序要求和消费模式。理解它们的定位比记住名称更重要。
Azure Event Grid 是轻量级事件路由服务,适合离散的、低频的状态变更通知。它采用推送模型,事件到达后主动调用订阅者的 Webhook 或 Azure 服务。典型场景是“资源创建后触发函数”“Blob 上传后启动处理”。Event Grid 不保证严格顺序,单事件最大 1 MB,适合反应式、事件量适中的场景。
Azure Event Hubs 是高吞吐事件流平台,适合每秒百万级事件的遥测、日志和流式分析。它采用拉取模型,消费者通过分区和偏移量控制读取位置,支持至少一次投递和分区内有序。Event Hubs 的保留期通常为 1 到 7 天,消费者可以在保留期内重放事件,这使它适合需要回放和流处理的场景。
Azure Service Bus 是企业级消息代理,提供队列和主题订阅两种模型。队列用于点对点命令分发,主题用于发布订阅。Service Bus 支持会话、死信队列、重复检测、事务和延迟消息,适合需要可靠投递、顺序处理和复杂路由的业务消息。它的吞吐量低于 Event Hubs,但消息语义更丰富。
Azure Queue Storage 是简单的队列服务,成本低、容量大,适合对消息语义要求不高的异步任务。它不保证顺序,单消息最大 64 KB,适合任务分发和后台处理。
此外,Azure Functions 和 Logic Apps 是常见的消费者与编排层。Functions 适合编写事件处理逻辑,Logic Apps 适合低代码连接 SaaS 和 Azure 服务。选择时可以先问三个问题:事件是离散通知还是连续流?需要顺序和事务吗?消费者是拉取还是推送?答案会直接指向合适的服务。
事件驱动适用场景与反模式
事件驱动并非万能。它最适合以下场景:多个下游系统需要响应同一业务事实,例如订单创建后同时触发库存、支付、通知和数据分析;系统需要削峰填谷,例如秒杀流量先写入事件通道再由消费者按能力处理;跨服务数据同步需要最终一致,例如用户资料变更后同步到搜索索引和推荐系统;以及需要审计和回放,例如金融交易事件保留后用于对账和重放。
常见的反模式同样值得警惕。把事件当命令用:发布 CreateOrder 这样的命令式事件,并要求特定消费者执行,实际上重新引入了耦合。事件携带过多数据:把整个数据库行塞进事件,导致事件膨胀且消费者依赖内部结构,应只携带标识和必要字段,消费者按需回查。忽略幂等性:事件通道通常至少一次投递,消费者必须能安全处理重复事件,例如用 OrderId + EventType 做去重键。用事件驱动做同步查询:请求方发布事件后等待响应,这既失去了异步优势,又增加了复杂度,应改用请求响应。缺少死信处理:消费者反复失败的事件如果没有死信队列,会阻塞后续处理或无限重试,必须配置死信和告警。