针对这个问题或困境的解决方案取决于您当前架构的一些信息。
- 您的微服务之间如何通信?
您是否使用命令/查询作为直接调用和通过某个队列的事件进行通信?
- 您的主数据有多大?
它是某种配置或少量缓存数据,作为某些常量或设置使用吗?
如果您的其中一种通信机制是通过来自某个队列的事件异步完成,并且您不处理非常频繁更改的大量数据,则我的建议是:
1. 创建专用主数据微服务。
该微服务将是您的主数据所有者。它将是唯一允许直接更改其中实体的服务。
2. 在更改主数据微服务中的每个实体时,在队列上发布事件。
每当有人在主数据微服务中创建、更新或删除实体时,您都将在某个队列上发布有关这些更改的事件。
3. 订阅主数据微服务事件。所有需要使用主数据微服务数据的其他微服务都会订阅其使用的实体的事件,并将它们本地保存在其数据库中。该数据或主数据子集将被保存为本地使用的副本。只有在主数据微服务发布实体已更改的事件时,这些主数据实体才能通过这些事件进行更改。任何其他类型的更改都将被禁止,因为这将在本地数据副本和其在主数据微服务中的真实源之间创建差异。
优点:
通过此方法,您只需拥有一个主数据信息的真实来源。所有其他微服务仅使用来自主数据微服务的所需数据或数据子集。他们可以忽略其他数据。另一个优点是,您的微服务可以独立运行,而不必直接调用主数据微服务以获取所需数据。
缺点:
缺点是您需要在多个微服务中复制数据。另一个问题是您需要处理分布式系统的复杂性,但您已经在做到这一点了;)
关于您提供的选择的一些评论:
在每个微服务中复制相同的主数据:优点:在应用程序缓存中工作时快速且无需查找,应用程序在内部进行访问。
缺点:需要在多个服务之间维护数据一致性,并且可能存在更新冲突。
建议:
与其在每个微服务中复制主数据,不如使用事件驱动的方法实现主数据微服务。这将确保数据的唯一来源并减少数据冗余。虽然这可能会增加系统的复杂性,但它可以避免数据一致性和更新冲突等问题。
将主数据作为真正的"source of truth"。缺点是:特定服务中主数据的任何更新都可能导致不一致性,因为在使用该数据进行通信时,对主数据的更新可能会在各个服务之间引起严重的一致性问题。
我的建议部分地涵盖了以上方法,只是没有直接调用。假设您将使用队列。即使您不使用队列,您也可以通过某些通知系统通知使用主数据微服务的微服务,然后仅在这种情况下让它们调用您的主数据微服务以获取最新数据。而不是在每个需要主数据的微服务内部进行调用。那样效率非常低下。
将主数据作为单独的微服务托管:优点是:单一的主数据源。缺点是:性能有所下降,因为每当查找发生时,它总是通过网络进行服务调用。
我从上面的建议中提出的方案是将这个点与您关于在每个微服务中复制数据的第一个点相结合。
创建分布式缓存并将其公开给多个微服务:这将打破数据的"Single Source o Truth"原则,但可以确保性能和一致性,因为它是一个写入实现。
我不建议这样做。有很多理由不能这样做,其中一些你已经提到了。在执行此操作时需要考虑的一件事是,您将为多个微服务拥有一个连接的单一故障点。这违反了微服务的主要原则之一。