【InfoQ】Zocdoc 的事件驱动架构实践( 二 )
本文插图
2. 查询
第二个挑战出现在实现从多个服务检索数据的查询时 。 如果这些服务中的任何一个需要来自多个 API 的数据来进行操作 , 则可能导致复杂的应用程序端连接 , 通常涉及许多同步请求 / 响应调用 。
当微服务像这样根据需要自由地调用其他微服务时 , 它会创建一个紧耦合的复杂的依赖关系图 ** , 很难进行推理和扩展(这也是我们过去一直在解决的问题) 。 此外 , 如果任何依赖的服务 API 发生故障 , 在处理时都需要仔细考虑 , 理清回退逻辑 。
本文插图
进化为事件驱动
对于许多像我们这样的应用程序 , 解决方案是使用事件驱动架构 。 这种架构中 , 在实体或域模型变化时 , 微服务会异步发布事件 , 而不是同步调用 API 。 其他微服务订阅这些事件并更新它们自己的实体 , 从而发布后续事件 。 这通常被称为基于编排的 Saga 模式 。
它支持跨多个服务的数据一致性 , 而不使用分布式事务 , 但提供的保证更弱 , 如最终一致性(通常称为 BASE 模型) 。 由于事件驱动的系统本质上是异步的 , 因此 , 它们通常比传统的 REST(或 API)架构响应更快 , 并且可以通过传入事件触发器来激活它们 。
这促成了服务之间的松耦合(和易伸缩) , 因为事件生产者不需要了解使用者以及它如何处理事件 。 它还消除了典型的请求 - 响应风格的 API 的阻塞 / 等待 , 释放了服务资源 。
事件使用者还可以维护自己的“物化视图”或数据副本 , 以供临时查询或与自己的数据进行连接 。 例如 , 我们的预约归因服务接收到一个 PracticeWebsiteAdded 事件 , 通知它新添加了 url , 它会更新自己的 PracticeUrl 数据存储副本 , 以便和 Booking 数据进行连接 。
虽然通常有许多模式属于事件驱动的范畴 , 但是这个特定的模式与 Martin Fowler 所说的事件传递状态转移是一致的 。 这种模式会生成大量重复的数据 , 但是由于目前存储成本较低 , 通常不需要考虑这个问题 。 另外 , 减少耦合和更好的弹性所带来的好处超过了对数据冗余的关注 。
本文插图
事件流和原子性
然而 , 要使这些事件驱动的系统可靠 , 必须满足一个核心条件——服务必须原子地写入其数据库并发布事件 。 这通常会导致以下基于事务的模式 。
1. 事务性发件箱模式
在这种方法中 , 你将在服务的数据库中创建一个额外的“发件箱”表 。 在接收到修改 / 创建业务实体的请求时 , 你必须更新你的实体表 , 并且 , 作为同一数据库事务的一部分 , 还必须在表示待发布事件的发件箱表中插入一条记录 。 然后 , 一个异步进程会监视该表中的新条目 , 并将这些事件发布到数据流或消息代理 。
本文插图
2. 事务日志跟踪或更改数据捕获(CDC)
这里的思想是跟踪数据库的事务日志 , 并将实体表中的每个更改作为事件发布 。 与基于轮询的方法相反 , 这种基于日志的更改数据捕获(CDC)几乎是实时的 , 而且开销非常小 。
Debezium 是一个流行的分布式平台 , 它为 MySQL、Postgres 和 SQL Server 等多个数据库提供了 CDC 连接器 。 如果你使用 DynamoDB 数据库的话 , AWS 以 DynamoDB 流的形式为 CDC 提供了一种更简单的机制 。 在任何 DynamoDb 表中 , 这些流都提供按时间顺序排列的条目级修改序列 , 并将这些信息存储在日志中长达 24 小时 。
推荐阅读
- InfoQ|从编译原理出发,看看你和资深 coder 差在哪儿?| 极客时间
- |联发科:我们一直很守规矩,华为事件纯属不符
- 极客微视数码说TB|iOS凌晨紧急推送!文字少事件大,建议iPhone用户都了解
- |PeckShield:5月共发生安全事件23起,受损金额高达数亿元
- 汽车通讯社|“瑞幸事件”后遗症?北汽或取代神州优车成神州租车第一大股东
- 黑客|全球最大的黑客组织“匿名者”发布视频称:黑人事件只是冰山一角
- 台积电|受华为事件冲击,台积电5nm扩建延至明年第一季度
- 木头筏子呀|兵来将挡!华为“芯片”事件反转,不用再担心芯片供应了
- 金融金融监管政策和公共卫生事件双重影响下 金融科技平台两极分化加剧
- InfoQ|宕机原因千千万,被雷劈了最无奈
