微服务之间的数据共享

时间:2017-01-13 17:52:49

标签: design-patterns architecture microservices aws-api-gateway data-sharing

当前架构:

enter image description here

问题:

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

  • 第一步: 前端验证微服务1(MS1)上的用户输入 I1
  • 第二步: 前端将 I1 和更多信息提交给微服务2

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

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

流程1:

  • 1.1用户X从MS2请求数据(MS2_Data)
  • 1.2用户X在MS1上保留数据(MS2_Data + MS1_Data)
  • 1.3 MS1使用B2B HTTP请求检查MS2_Data的完整性
  • 1.4 MS1使用MS2_Data和MS1_Data来持久化数据库1并构建HTTP响应。

流程2:

  • 2.1用户X已经存储在本地/会话存储
  • 上的数据(MS2_Data)
  • 2.2用户X在MS1上保留数据(MS2_Data + MS1_Data)
  • 2.3 MS1使用B2B HTTP请求检查MS2_Data的完整性
  • 2.4 MS1使用MS2_Data和MS1_Data来持久化数据库1并构建HTTP响应。

方法

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

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

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

注意 每次微服务2需要来自微服务1的信息时,执行B2B http请求。 (HTTP请求使用ETAGCache Control: max-age)。怎么避免这个?

架构目标

enter image description here

微服务1需要来自微服务2的数据,以便能够在MS1数据库上保留MS1_Data和MS2_Data,因此使用代理的ASYNC方法不适用于此。

我的问题是,是否存在设计模式,最佳实践或框架以实现这种推力沟通。

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

MS2_Data只是MS1必须用来维护数据完整性的产品SID或供应商SID之类的实体SID。

可能的解决方案

enter image description here

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

当然,上述解决方案仅适用于微服务的共享UUID / GUID。对于完整数据,事件总线用于以异步方式(事件源模式)跨微服务分发事件和数据。

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

相关问题和文档:

4 个答案:

答案 0 :(得分:2)

从问题和评论中我了解到您正在尝试重新排列块以提高系统性能。如图所示,您建议不再使用microservice1查询microservice2,网关将查询microservice2,然后查询microservice1,从微服务器2获取信息。

因此我不明白这会如何显着提高系统性能,而是改变似乎只是改变逻辑。

为了解决这种情况,应该提高关键微服务2的性能。它可以通过分析和优化microservice2软件(垂直扩展)和/或您可以在多个服务器上引入负载平衡(水平扩展)和执行microservice2来完成。在这种情况下使用的设计模式是Service Load Balancing pattern

答案 1 :(得分:2)

在我的问题上查看可能的解决方案部分:

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

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

答案 2 :(得分:1)

然而,如果没有在框内“查看”,很难判断任何解决方案的可行性:

  • 如果您唯一关心的是停止前端可能篡改数据,您可以创建一种MS2发送到前端的数据包的“签名”,并将签名传播到MS1与数据包一起。签名可以是与从微服务共享的种子以确定性方式生成的伪随机数相关联的分组的散列(因此MS1可以重建与MS2相同的伪随机数而无需额外的B2B HTTP请求,然后验证包的完整性)。

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

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

希望它有所帮助!

答案 3 :(得分:1)

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

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

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

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

相关的SO问题herehere讨论了非常类似的问题,请考虑一下。