服务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(但它仍然是灰色地带,请注意,这可能会让你的生活变得困难,这取决于服务a随时间的发展(

让我们尝试创建一些真实的生活场景来更好地理解:

我们正在youtube上工作。

  1. 服务A管理作为用户的实体
  2. 服务B为每个用户运行一个作业-如果用户处于活动状态,则使用AI更新用户偏好

在这种情况下,简单地从服务a读取数据是非常有意义的(即使存储成本不高(。

我们应该这样做,因为执行起来非常简单。此外,如果服务A关闭,暂时不会运行此作业对业务来说也是可以的。

现在是另一个商业案例:

让我们试着创造一些真实的生活场景来更好地理解:

我们正在youtube上工作。

  1. 服务A管理作为用户的实体
  2. 服务B-如果用户处于非活动状态,则发送电子邮件通知

我当然想使用事件来实现这一点。

现在我的主要观点是,当你想被动地做一些操作时,通常使用事件,并且依赖性很低。否则,从主服务读取数据,因为这很简单,而在另一个服务中管理数据(很快可能成为多个服务B(将在管理时产生问题

最新更新