【问题标题】:NserviceBus saga calling out web servicesNserviceBus 传奇调用 Web 服务
【发布时间】:2018-04-04 11:50:47
【问题描述】:

在 NServiceBus documentation 中声明 sagas 不应调用 Web 服务:

除了与自己的内部状态交互之外,saga 不应访问数据库、调用 Web 服务或访问其他资源 - 既不直接也不通过将此类依赖项注入其中而间接访问。

由于没有解释为什么不这样做,我想请社区帮助我解决这个问题。

我明白为什么我不能查询数据库:状态可能在发出事件和处理它之间发生了变化。我不明白的部分是关于网络服务的。

为什么 POST 是不好的做法,比如使用给定 ID 向 ShipOrder 命令发送 Web 服务?

【问题讨论】:

标签: architecture nservicebus saga


【解决方案1】:

通常最好通过https://discuss.particular.net/ 或通过定期支持向特定软件团队本身提出此类问题。原因是这些问题相当开放,并且往往会创建一个回复线程。

由于我在为特定软件工作,让我们在此继续。您可以随时复制问题/线程。

主要原因是saga state的可能争用和一致性。根据持久化器,可​​检索 saga 状态并使用悲观或乐观锁定进行持久化。无论哪种方式,如果事务花费的时间太长,则可能会出现另一条与同一个 saga 实例相关的消息。它可能在不同的(并发)线程(或者可能是横向扩展的端点)上进行处理,并且它将立即失败(悲观锁定)或尝试保持状态(乐观锁定)。消息将被重试。

这是正常行为,不是可以避免的。然而,锁打开的时间越长,它发生的可能性就越大。通常的建议是除了业务流程的编排之外,不要做任何其他事情。因此,甚至不需要检索或存储您自己的业务数据。但是对于 web 服务,您无法控制 web 服务,并且在消息失败之前可能需要连接超时或更长时间。相关消息的失败速度会更快,并且很可能最终会出现在错误队列中。

除了协调业务流程和“只是”发送消息之外,不做任何其他事情就可以避免这种情况。尽可能缩短对数据的锁定。

【讨论】:

  • 所以我猜它非常依赖于 Saga 构造本身。在我的情况下,Saga 将只管理一组服务,例如 - 调用 service1 - 当 service1 完成工作时调用 service2 - 当 service2 完成工作时我想在这种情况下我应该是安全的?
  • 如果可以按顺序完成,我会创建两个调用这些服务的处理程序。然后从我的传奇火灾消息到那些处理程序。传奇将是检查一切是否完成。因此,两个处理程序都需要回复传奇,说明一切正常。 Saga 可以设置 24 小时左右的超时时间。如果超时,我们可以验证工作是否已经完成。如果没有,我们会在其他地方发出警报。
【解决方案2】:

除了丹尼斯的功能性回答,我还觉得这里有代码健康/代码架构方面的问题,特别是关注点分离。 saga 的功能是编排——对长期运行的业务流程进行建模。我建议让 saga 调用一个方法来调用 web 服务的成本非常低,并且代码健康的增加相对于成本来说是很大的。

换一种说法,我建议编排是业务逻辑,因为调用 Web 服务更像是基础架构代码,而不是业务逻辑。

这种区别很重要的原因有很多,但首先想到的是您的测试策略。您对基础设施代码的测试策略很可能与您对业务逻辑的测试策略不同。当一个班级同时有这两种情况时,这很难做到。

【讨论】:

  • 我同意你关于分离关注点的观点。我的 saga 只是通过接口调用一些服务(在后台调用 web 服务),所以 saga 本身的唯一代码与编排有关。但是给定的文档说我不应该从 saga 间接调用 Web 服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多