10

致力于将庞大的单体应用程序迁移到微服务范式,不用说域识别和映射到不同的微服务和编排是一项艰巨的任务。现在,由于之前的应用程序在同一个模式中共享主数据,在新的范例中我很难管理它,我的选择是:

  1. 在每个微服务中复制相同的主数据: 优点:当缓存在应用程序中快速运行且无需查找时,应用程序本身就充当了真正的事实来源。缺点:特定服务中主数据的任何更新都可能导致不一致,而服务尝试使用此数据相互通信,主数据的更新可能会导致严重的一致性问题。
  2. 将主数据作为单独的微服务托管: 优点:主数据的单一来源。缺点:性能下降,因为它总是在查找发生时通过网络进行服务调用。
  3. 创建分布式缓存并将其公开给多个微服务:将打破微服务数据的“单一来源即真相”原则,但可以通过写入实现来确保性能和一致性。

对上述任何想法或任何实施策略的任何想法都会真正有帮助......

瓦布哈夫

4

2 回答 2

17

此特定问题或困境的解决方案取决于有关您当前架构的一些信息。

  • 您的微服务如何相互通信?您是否将命令/查询用作某些队列上的直接调用和事件?

  • 你的主数据有多大?是某种配置还是少量现金数据被用作某种常量或设置?

如果您的一种通信机制与来自某个队列的事件异步完成,并且您没有处理经常更改的大量数据,那么我的建议是:

1. 创建专用的主数据微服务。 这个微服务将是您的主数据的所有者。这将是唯一允许直接更改其中的实体的一种。

2. 将事件发布到主数据微服务中每个实体的更改队列。每当有人在主数据微服务中创建、更新或删除实体时,您都会将有关这些更改的事件发布到某个队列。

3.订阅主数据微服务事件。 所有其他需要主数据微服务数据的微服务将订阅它使用的实体的事件并将它们本地保存在其数据库中。此数据或主数据子集将保存为副本以供本地使用。只有当主数据实体的“真实来源”主数据微服务发布它们已更改的事件时,才能使用这些事件更改此主数据实体。任何其他类型的更改都将被禁止,因为它会在该数据的本地副本与其在主数据微服务中的真实来源之间产生差异。

优点:

使用这种方法,您的主数据只有一个真实来源。所有其他微服务将仅使用它们需要的主数据微服务中的数据或数据子集。他们可以简单地忽略其他数据。另一个优点是您的微服务可以自己运行,而无需直接调用主数据微服务来获取它需要的一些数据。

缺点

缺点是您需要在多个微服务中复制数据。另一个问题是您需要处理分布式系统的复杂性,但您已经在这样做了;)

对您提供的选择的一些评论:

在每个微服务中复制相同的主数据: 优点:当缓存在应用程序中快速运行且无需查找时,应用程序本身就充当了真正的事实来源。缺点:特定服务中主数据的任何更新都可能导致不一致,而服务尝试使用此数据相互通信,主数据的更新可能会导致严重的一致性问题。

我上面的建议已经部分涵盖了这种方法,只是没有直接调用。假设您将使用队列。即使您不使用队列,您也可以通过一些通知系统通知使用主数据微服务的微服务,然后才让他们调用您的主数据微服务以获取最新信息数据。并且不要对需要主数据的微服务内部的每个操作进行调用。那将是非常低效的。

将主数据作为单独的微服务托管: 优点:主数据的单一来源。缺点:性能下降,因为它总是在查找发生时通过网络进行服务调用。

我从上面建议的方法是与此方法和您关于在每个微服务中复制数据的第一点相结合的方法。

创建分布式缓存并将其公开给多个微服务:将打破微服务数据的“单一来源即真相”原则,但可以通过写入实现来确保性能和一致性。

我不建议这样做。为什么不这样做的原因有很多。你已经提到的一些。执行此操作时要考虑的一件事是,您将有 1 个连接多个微服务的单点故障。这违背了微服务的主要原则之一。

于 2019-08-31T17:56:48.157 回答
0

我们遵循的一种方法如下所示;

  1. 创建主数据实体的逻辑分组,这样我们就不会最终创建一个 SUPER BIG MONOLITH 微服务。

  2. 通过微服务提供对逻辑分组的主实体的管理(创建/更新/删除/读取)。所以我们有 5 到 6 个微服务来管理不同的主数据实体逻辑组。

  3. 每当任何一个功能模块请求主数据实体时,都会先在Redis Cache中查找,如果没有找到,则调用Reference数据逻辑组对应的fetch API微服务。

  4. 微服务的 Fetch API 有将主数据实体放入 Redis Cache 的实现。这样,对同一实体的任何后续请求都将在 Redis 缓存中用于其他功能模块。

  5. Redis 缓存在请求 Fetch API 或更新值对象时得到更新。

优点

  1. 所有值对象都从 Redis 缓存集中访问。
  2. Redis 缓存提供了更快的读取速度,而不是每次都通过主数据实体的 Fetch API。

缺点

  1. 识别单个主数据实体的密钥需要传递给其他功能模块。
于 2021-05-21T08:45:18.717 回答