database - 服务 B 依赖于服务 A 中的数据:重复数据还是按需检索?
问题描述
这是一个微服务设计问题,它是我想解决的现实问题的简化。
服务 A 具有可以处于活动或不活动状态的实体。
[
{
id: "a46e6cc7-97ca-4570-b3f3-2be00ca9dab5",
name: "foo",
active: true
},
{
id: "eb1ced31-eccc-4ad6-a695-5c6c76cab7a5",
name: "bar",
active: false
},
{
id: "ef332044-9e66-4a0b-91ed-c16a2537e848",
name: "baz",
active: true
}
]
服务 B 具有与服务 A 的实体相关的作业,并且仅应在实体处于活动状态时运行(根据业务规则)。
选项 1:服务 B 不存储作业是否应该运行。
[
{
id: "39cf3321-34d1-4557-b1c4-ca628c191b92",
entityId: ""a46e6cc7-97ca-4570-b3f3-2be00ca9dab5",
start: "Thu Nov 29 2018 08:40:27 GMT-0800 (Pacific Standard Time)",
ended: null,
recurrence: "hourly"
},
{
id: "77296d22-564f-4289-8327-f23bceb1d400",
entityId: "a46e6cc7-97ca-4570-b3f3-2be00ca9dab5",
start: "Tu Nov 27 2018 15:56:01 GMT-0800 (Pacific Standard Time)",
ended: null,
recurrence: "hourly"
},
{
id: "2916a920-13a3-46f6-9ffd-d7629163924a",
entityId: "eb1ced31-eccc-4ad6-a695-5c6c76cab7a5",
start: "Wed April 01 2018 00:00:00 GMT-0800 (Pacific Standard Time)",
ended: Thu April 01 2019 00:00:00 GMT-0800 (Pacific Standard Time),
recurrence: "daily"
},
]
当计划运行作业时,它会检查
if Service A has j.entityId = true
run j
使用服务 A 的 API。
选项 2:服务 B 存储作业是否应该运行
[
{
id: "39cf3321-34d1-4557-b1c4-ca628c191b92",
entityId: ""a46e6cc7-97ca-4570-b3f3-2be00ca9dab5",
active: true,
start: "Thu Nov 29 2018 08:40:27 GMT-0800 (Pacific Standard Time)",
ended: null,
recurrence: "hourly"
},
{
id: "77296d22-564f-4289-8327-f23bceb1d400",
entityId: "a46e6cc7-97ca-4570-b3f3-2be00ca9dab5",
active: true,
start: "Tu Nov 27 2018 15:56:01 GMT-0800 (Pacific Standard Time)",
ended: null,
recurrence: "hourly"
},
{
id: "2916a920-13a3-46f6-9ffd-d7629163924a",
entityId: "eb1ced31-eccc-4ad6-a695-5c6c76cab7a5",
active: false,
start: "Wed April 01 2018 00:00:00 GMT-0800 (Pacific Standard Time)",
ended: Thu April 01 2019 00:00:00 GMT-0800 (Pacific Standard Time),
recurrence: "daily"
},
]
其存储通过服务 A 的通知保持最新:
Entity e changes => publish e => Service B updates accordingly
以下是我看到的支持每个选项的论点。
选项 1 参数:
- 由于数据不重复,存储成本更低
- 当一个作业计划运行时,它总是有关于它是否应该处于活动状态的最新信息(更多“一致性”?)
- 不必处理跨服务同步数据的复杂性。在这个例子中,只有服务 B 依赖于来自 A 的数据,但是想象一下如果有服务 X0、...、X1000 都需要知道一个实体是否处于活动状态,这将是多么复杂。
选项 2 参数:
- 服务是真正独立的:如果 A 没有运行,B 仍然可以运行
- 更少的聊天服务(更少的网络传输成本)
- 虽然可能更复杂,但复制/传播数据的复杂性迫使服务不共享或共享很少
解决方案
这应该取决于您的需求以及电话的频率,但在此之前我想更正几点。
存储成本真的不应该是一个问题,保持数据同步的努力以及之后的后果是。健谈还不错,它可能会使事情变得有点复杂,但是有一些方法可以让事件驱动系统创造奇迹并且仍然可以维护。
服务必须是独立的,同意,但这并不意味着它们不应该尊重边界。订单服务需要用户数据,但这并不能证明将所有用户数据保留在订单服务中。它并没有使它独立,但它只是使服务膨胀并使订单担心它不应该真正关心的事情。
因此,在您的情况下,我更愿意进行 api 调用(并为服务 A 提供 SLA 以快速响应、缓存或其他),但我会避免在我的系统中缓存其他人的数据。但是,有时当您的服务 B 被调用时,例如每分钟 n 次并且 n 越来越大,那么您可能会倾向于方法 b(但它仍然是灰色区域并且要小心,这可能会让您的生活变得困难取决于 serviceA 如何随时间演变)
推荐阅读
- angular - 如何在 Angular 中搜索两个文档而不是两个文档时发出一个服务请求?
- javascript - 动态具有多个 colspan 的表格单元格
- ruby-on-rails - '(node:7103) DeprecationWarning: 'root' is deprecated, use 'global''
- go - 如何在 Gin 中提供静态文件
- sql - PostgreSQL 在特定条件下获得最高值
- javascript - 如何删除在发布/订阅数据存储中注册的回调?
- ios - 如何在可映射类中附加数据
- django - 从 ReactJs/Axios 下载的 Zip 文件已损坏
- drupal - 我可以在 drupal 8 的基于组件的主题中使用什么基本主题?
- java - java.lang.ClassCastException:子类不能转换为超类