微服务之间的数据共享

Data Sharing between micro services

当前架构:

问题:

我们在前端和后端层之间有一个两步流程。

微服务 2 (MS2) 需要验证来自前端的 I1 的完整性。如何避免对 MS1 的新查询?什么是最好的方法?

我尝试优化的流程删除了步骤 1.3 和 2.3

流程 1:

流程 2:

接近

一种可能的方法是在 MS2 和 MS1 之间使用 B2B HTTP 请求,但我们会在第一步中重复验证。 另一种方法是将数据从 MS1 复制到 MS2。然而,由于数据量及其波动性,这是令人望而却步的。复制似乎不是一个可行的选择。

我认为更合适的解决方案是前端负责在微服务2上获取微服务1所需的所有信息并将其传递给微服务2。这将避免所有这种B2B HTTP 请求。

问题是微服务1如何信​​任前端发送的信息。也许使用 JWT 以某种方式对来自微服务 1 的数据进行签名,微服务 2 将能够验证消息。

备注 每次微服务 2 需要来自微服务 1 的信息时,都会执行 B2B http 请求。 (HTTP 请求使用 ETAG and Cache Control: max-age)。如何避免这种情况?

架构目标

微服务 1 需要微服务 2 的数据按需持久化 MS1_Data 和 MS2_Data 在 MS1 数据库上,所以 ASYNC 方法使用经纪人不适用于此处。

我的问题是是否存在一种设计模式、最佳实践或框架来实现这种推力交流。

当前架构的缺点是每个微服务之间执行的 B2B HTTP 请求的数量。即使我使用缓存控制机制,每个微服务的响应时间也会受到影响。每个微服务的响应时间都很关键。这里的目标是获得更好的性能,以及如何使用前端作为网关在多个微服务之间分发数据,但使用 推力通信

MS2_Data 只是一个实体 SID,例如 MS1 必须用来维护数据完整性的产品 SID 或供应商 SID。

可能的解决方案

想法是将网关用作 api 网关请求处理,它将缓存来自 MS1 和 MS2 的一些 HTTP 响应,并将它们用作对 MS2 SDK 和 MS1 SDK 的响应。这样就不会在 MS1 和 MS2 之间直接进行通信(SYNC 或 ASYNC),也避免了数据重复。

当然上面的方案只是针对跨微服务共享的UUID/GUID。对于完整数据,事件总线用于以异步方式(事件溯源模式)跨微服务分发事件和数据。

灵感:https://aws.amazon.com/api-gateway/ and https://getkong.org/

相关问题及文档:

不看 "inside" 方框就很难判断任何解决方案的可行性,但是:

  • 如果您在这里唯一关心的是阻止前端可能篡改数据,您可以创建一种 "signature" 的数据包,由 MS2 发送到前端并将签名与数据包一起传播到 MS1。签名可以是数据包的哈希值,该哈希值与以确定方式从微服务共享的种子生成的伪随机数相结合(因此 MS1 可以重新创建与 MS2 相同的伪随机数,而无需额外的 B2B HTTP 请求,然后验证数据包的完整性)。

  • 我想到的第一个想法是验证数据的所有权是否可以修改。如果 MS1 必须频繁访问 MS2 的数据子集,则可以将该子集的所有权从 MS2 转移到 MS1。

  • 在理想的世界中,微服务应该是完全独立的,每个微服务都有自己的持久层和适当的复制系统。你说代理不是一个可行的解决方案,那么共享数据层呢?

希望对您有所帮助!

从问题和评论中我了解到您正在尝试重新排列块以提高系统性能。如图表所述,您建议网关查询微服务 2 而不是微服务 1 查询微服务 2,然后查询微服务 1,向其提供来自微服务 2 的信息。

因此,我看不出这将如何显着提高系统性能,而是这种变化似乎只是改变了逻辑。

要补救这种情况,应增强关键微服务 2 的性能。可以通过分析和优化 microservice2 软件(垂直扩展)and/or 来完成,您可以引入负载平衡(水平扩展)并在多个服务器上执行 microservice2。本例中使用的设计模式是Service Load Balancing pattern.

您可以考虑将 b2b 通信的同步方式更改为使用 publish-subscribe 模式的异步方式。在那种情况下,服务操作将更加独立,您可能不需要一直执行 b2b 请求。

在分布式系统中加快速度的方法是通过非规范化。如果 ms2data 很少更改,例如您阅读它的次数多于重写它,您必须跨服务复制它。通过这样做,您将减少延迟和时间耦合。在许多情况下,耦合方面可能比速度更重要。

如果 ms2data 是关于产品的信息,则 ms2 应该将包含 ms2data 的 ProductCreated 事件发布到总线。 ms1 应订阅此事件并将 ms2data 存储在其自己的数据库中。现在,只要 ms1 需要 ms2data,它就会在本地读取它,而不需要向 ms2 执行请求。这就是时间解耦的意思。当您遵循此模式时,您的解决方案将变得更加容错并且关闭 ms2 不会以任何方式影响 ms1。

考虑阅读描述微服务架构中同步通信背后问题的 good series of articles

相关的 SO 问题 and here 讨论非常相似的问题,考虑看看。

查看关于我的问题的可能的解决方案部分:

想法是将网关用作 api 网关请求处理,缓存来自 MS1 和 MS2 的一些 HTTP 响应,并将它们用作对 MS2 SDK 和 MS1 SDK 的响应。这样就不会在 MS1 和 MS2 之间直接进行通信(SYNC 或 ASYNC),也避免了数据重复。

灵感:https://aws.amazon.com/api-gateway/ and https://getkong.org/