微服务之间的数据共享

Posted

技术标签:

【中文标题】微服务之间的数据共享【英文标题】:Data Sharing between micro services 【发布时间】:2017-05-29 04:19:35 【问题描述】:

当前架构:

问题:

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

第一步: 前端验证来自用户在微服务 1 (MS1) 上的输入 I1 第二步: 前端向微服务提交I1等信息2

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

我正在尝试优化的流程移除步骤 1.3 和 2.3

流程一:

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 请求使用ETAG 和Cache Control: max-age)。如何避免这种情况?

架构目标

微服务 1 需要来自微服务 2 的按需数据,才能将 MS1_Data 和 MS2_Data 持久化到 MS1 数据库中,因此使用代理的 ASYNC 方法在这里不适用。

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

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

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

可能的解决方案

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

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

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

相关问题和文档:

How to sync the database with the microservices (and the new one)? https://auth0.com/blog/introduction-to-microservices-part-4-dependencies/ Transactions across REST microservices? https://en.wikipedia.org/wiki/Two-phase_commit_protocol http://ws-rest.org/2014/sites/default/files/wsrest2014_submission_7.pdf https://www.tigerteam.dk/2014/micro-services-its-not-only-the-size-that-matters-its-also-how-you-use-them-part-1/

【问题讨论】:

当前解决方案的缺点是什么?它更简单,每个服务只需返回请求的数据,而不必进入消息身份验证业务。 缺点是每个微服务之间执行的 B2B HTTP 请求的数量。即使我使用缓存控制机制,每个微服务的响应时间也会受到影响。每个微服务的响应时间至关重要。这里的目标是归档更好的性能,以及如何使用前端作为网关在多个微服务之间分发数据,但使用推力通信。 @dbugger 你怎么看? 我看不出你是如何减少整体流量的,你只是重新安排它并添加加密的复杂性。 你能用特定领域的术语描述插图组件的动态行为吗?例如。 “用户 X 查询配置文件数据,需要同时查询服务 A 和 B”。因为目前还不清楚这些 b2b 请求是关于什么的。 @IlliakaillI 我更新了这个问题,提供了有关我当前架构和我要归档的内容的更多详细信息。请查看流程部分。 【参考方案1】:

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

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

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

【讨论】:

可以帮忙解决这个问题吗? ***.com/questions/44083919/…【参考方案2】:

根据问题和 cmets,我了解到您正在尝试重新排列块以提高系统性能。如图表所述,您建议网关不是查询 microservice1 查询 microservice2,而是查询 microservice2,然后查询 microservice1,向其提供来自 microservice2 的信息。

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

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

【讨论】:

我更新了这个问题,提供了有关我当前架构和我要归档的内容的更多详细信息。我已经在每个微服务上使用负载平衡和垂直扩展。请查看流程部分。 请检查我更新的问题和可能的解决方案部分。你怎么看?【参考方案3】:

但是,如果不查看“内部”框框,则很难判断任何解决方案的可行性:

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

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

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

希望对你有帮助!

【讨论】:

我更新了这个问题,提供了有关我当前架构和我要归档的内容的更多详细信息。您能否提供有关的更多信息/链接。迄今为止最好的答案! 请检查我更新的问题和可能的解决方案部分。你怎么看?【参考方案4】:

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

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

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

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

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

【讨论】:

我更新了这个问题,提供了有关我当前架构和我要归档的内容的更多详细信息。此处不能使用异步方式,因为:微服务 1 需要微服务 2 中的数据按需才能将 MS1_Data 和 MS2_Data 持久化到 MS1 数据库中,因此此处不适用使用代理的 ASYNC 方式。跨度> 谢谢 Leonel,看看我根据提供的新信息更新的答案。不幸的是,您没有指定 data1 和 data2 的含义,因此很难给出更有意义的答案。数据是图像吗?是认证密钥吗?是用户资料吗?还是不清楚。 MS2_Data 只是一个实体 SID,如产品 SID 或供应商 SID,MS1 必须使用它来维护数据完整性。 那么你应该考虑在这两个服务中存储这个id。我已经用关于如何做到这一点的详细描述更新了我的答案。

以上是关于微服务之间的数据共享的主要内容,如果未能解决你的问题,请参考以下文章

在微服务之间共享代码 - 在这种情况下是不是合理?

微服务架构中如何在微服务之间共享java模型

在微服务之间共享文件

我应该在微服务之间共享我的库吗?

微服务架构:跨服务数据共享

如何使用微服务架构处理共享数据源