【问题标题】:IDDD Red Book: Chapter 13 Integrating Bounded Context, RESTful Temporal DecouplingIDDD 红皮书:第 13 章集成限界上下文,RESTful 时间解耦
【发布时间】:2019-08-21 23:51:41
【问题描述】:

书中第 458 页。

“不过,我们可以通过依赖来在一定程度上克服这个问题 在 RESTful 资源上,消费者自治的障碍较小。 即使 RESTful(或 RPC)是你唯一的手段 整合,你可以创造时间解耦的错觉 通过在您自己的系统中使用计时器或消息传递。那 只有当一个 计时器到时或收到消息时。如果遥控器 系统不可用,可以取消定时器阈值,或者 如果使用消息传递,则可以否定地确认消息 经纪人并重新交付”

上下文:

  • 我有一个客户端服务 C

  • 我有一个服务器服务 S

  • C --calls--> S

  • 想增加C的自主性,减少对S的依赖

问题:

  • 这本书说(在上面的段落中)我可以使用计时器或消息传递来使用“时间解耦”。所以这对我来说意味着 C 不再需要阻止并等待 S 的立即响应?对吗?

  • 使用定时器进行时间解耦:C 仅在定时器超时且远程系统 (S) 不可用时才在 S 上调用定时器阈值。那是什么意思?你能澄清一下吗?
    我知道 C 仅在计时器超过 10 秒时才会调用?对吗?
    不清楚“计时器阈值后退”如何对此有所帮助?

  • 使用消息传递的时间解耦:C 仅在收到消息并且远程系统 (S) 不可用时才在 S 上调用消息,该消息被否定确认。那是什么意思?你能澄清一下吗?
    C 仅在从哪里收到“收到消息”时才调用 S?
    如果没有收到消息,则“...消息可以被代理否定并重新传递”,这里不清楚事件顺序吗?

如果可以,请举例说明。谢谢。

【问题讨论】:

标签: rest domain-driven-design integration bounded-contexts


【解决方案1】:

这本书说(在上面的段落中)我可以使用“时间 解耦”使用计时器或消息传递。所以这对我来说意味着 C 没有 更长时间必须阻止并等待 S 的立即响应?就是它 对吗?

是的,它用于在上游 BC(服务器“S”)提供 REST API 而不是将消息发布到中间件队列时实现两个有界上下文 (BC) 之间的异步集成。

使用定时器的时间解耦:C 只在定时器时调用 S 过去,如果远程系统 (S) 不可用,则计时器 阈值回退。那是什么意思?你能澄清一下吗?一世 了解 C 仅在计时器超过 10 秒时才会调用 例子?那是对的吗?不清楚如何支持“计时器阈值” off”可以帮助解决这个问题吗?

因此,下游 BC (C) 与上游 BC (S) 集成,方法是在每次计时器经过时(例如每 10 秒,如您所说)轮询 S 的 REST API。在 API 不可用时关闭计时器阈值,意味着客户端将在正常间隔重试轮询,与计时器无关。

示例:

C --POLL--> S @ 00:00
C --POLL--> S @ 00:10
C --POLL--> S @ 00:20
C --POLL--> S @ "every 10 sec"
S is-down
C --POLL--> S @ 00:00 (timer is backed-off)
S is-down
C --POLL--> S @ 00:00 (timer is backed-off)
S is-up
C --POLL--> S @ 00:10
C --POLL--> S @ 00:20
C --POLL--> S @ "every 10 sec"

使用消息传递的时间解耦:C 仅在 S 上调用 收到消息,如果远程系统 (S) 不可用 消息被否定确认。那是什么意思?你可以吗 阐明? C仅在收到“收到消息”时才调用S 在哪里?如果没有收到消息,那么“......消息可以是 向经纪人否定承认并重新交付”,不清楚 这里的事件顺序?

每次 C 接收到由客户端 BC 内的内部代理发布的消息(不是 C 和 S 之间的消息队列)时都会进行轮询,而不是使用计时器。向代理返回否定确认是为了告诉代理它必须重新传递消息(因为无法执行对 S 的调用)。所以 broker 会再次向 C 发送相同的消息,C 会重试对 S 的调用。

更新:

以下是 Vaughn Vernon 在他的另一本书“DDD 提炼”中关于这个主题的说法:

“使用 REST 实现异步

可以使用基于 REST 的轮询顺序增长的资源集来完成异步消息传递。使用后台处理,客户端将不断轮询服务 Atom 提要资源,该资源提供不断增加的领域事件集。这是一种维护服务和客户端之间的异步操作的安全方法,同时提供服务中继续发生的最新事件。如果服务由于某种原因变得不可用,客户端将简单地按正常间隔重试,或者通过重试退出,直到提要资源再次可用。

在实现领域驱动设计中详细讨论了这种方法。"

【讨论】:

  • 我在上面添加了一个 Timer 示例。我理解计时器回退的方式是它回到零,对吗?那么在这里使用定时器的好处是,如果客户端看到 00:00 它应该等待至少 10 秒?如果它看到非零,那么它知道很有可能 S 仍然可用?
  • 在消息传递的情况下,我假设代理不断发送消息并且这些消息仅作为轮询 S 的触发器?在这种情况下,如果 C 接收到轮询 S 的代理消息并且 S 已关闭:C 应该只等待下一个 prod 消息,即看不到来自 C 的 NAK 消息的使用?
  • 好吧,我从来没有实现过算法(在红皮书 IDDD 中我认为有实现),我不知道这是否意味着重置计时器(或者干脆停止它)。我所知道的是,如果在进行某个轮询时服务不可用,客户端会停止它正在执行的顺序轮询,并重试失败的轮询,直到服务再次可用。我已经用 Vaughn Vernon 的更多信息更新了答案。
  • 如果使用消息而不是计时器实现,消息会告诉何时轮询 S(它相当于计时器何时结束)。如果由于服务不可用而导致轮询失败,则发送给代理的 NAK 是为了让它知道它必须重新发送相同的消息,而不是序列中的下一条消息。
猜你喜欢
  • 1970-01-01
  • 2013-11-27
  • 2015-08-04
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多