design-patterns - 微服务设计:改变数据需求或模式
问题描述
假设我们有 2 个服务,服务 A 和服务 B。它们通过事件溯源相互交互。服务 发布事件(使用字段 f1、f2、f3 创建的 entity1)。服务 B 使用字段 f1 和 f2 制作自己的 entity1 副本。现在我们如何解决这两种情况。
- 服务 2 的新需求和 f3 的需求。service2 必须如何更新其本地数据?
- 服务 1 的架构更改。服务 2 必须如何更新其本地数据和架构?
在场景 2 中,服务通过模式紧密耦合,并可能导致错误,这与事件溯源目标相矛盾。我们如何解决这个问题?
解决方案
对于场景 1,实体的视图更改为合并已发布到事件流的字段,最简单的事情可能是重播事件(例如,如果事件流在 Kafka 上,则使用带有 的新消费者组auto.offset.reset=earliest
)使用新字段的事件处理程序。这通常会非常快,允许您在运行先前版本服务的时间窗口中运行此重建;否则,您应该能够在新实例旁边运行服务 B 的旧实例(如果它们正在写入不同的数据库):当新实例赶上时,您将任何流量转移到服务 B 以使用新实例和拆除旧的(基本上是蓝绿色部署)。
对于第二种情况,有一些选择:
- 您可以定义一个
Entity1CreatedV2
适合新模式的事件(这可能需要先更新消费者以了解新事件) - 如果旧模式中的字段未更改(即模式更改是严格附加的),您可以保留旧
Entity1Created
消息,然后为新字段设置事件。请注意,为服务 A 中的现有实体提供架构更改可能会驱使您使用此解决方案,尤其是在服务 A 没有命令采购的情况下(命令采购可能允许您假装新架构永远存在)。
推荐阅读
- firebase - 发布新的Vue应用程序版本时如何清除chrome中的缓存
- r - 如何快速遍历所有自变量组合?
- r - 将 lattice xyplot 用于具有点和线的分组数据
- c# - 如何在 Xamarin 中设置新保存文件的名称?
- javascript - WebRTC:使用 Mesibo 视频/音频聊天的浏览器中的 ICE 失败错误
- python - 使用烧瓶从 HTML 表中删除单个 SQLAlchemy 行
- c# - Ant Design Blazor 显示消息回调不起作用
- c++ - 如果扩展是核心扩展,我如何签入 Vulkan 代码?
- regex - 使用正则表达式选择文本匹配单词或模式之后的所有内容(类似的主题,但文本不是固定模式,除了 1 个字符)
- javascript - Expo React Native 错误:未处理的 JS 异常:清单必须指定 logUrl