NserviceBus 传奇调用 Web 服务
NserviceBus saga calling out web services
在 NServiceBus documentation 中声明 sagas 不应调用 Web 服务:
Other than interacting with its own internal state, a saga should not access a database, call out to web services, or access other resources - neither directly nor indirectly by having such dependencies injected into it.
由于没有解释为什么不这样做,我想请社区帮助我解决这个问题。
我明白为什么我无法查询数据库:状态可能在发出事件和处理事件之间发生了变化。我不明白的部分是关于网络服务。
为什么说 POST 使用给定 ID 的 ShipOrder 命令发送 Web 服务是不好的做法?
通常最好在 https://discuss.particular.net/ 上或通过常规支持向特定软件团队本身提出此类问题。原因是这些问题相当开放,往往会产生一个回复线程。
既然我在为Particular Software工作,那我们就在这里继续吧。您可以随时复制 question/thread.
主要是saga状态可能存在的争用和一致性问题。根据持久性,saga 状态被检索并使用悲观或乐观锁定进行持久化。无论哪种方式,如果交易花费的时间太长,则可能会收到与同一传奇实例相关的另一条消息。它可能在不同的(并发)线程(或者可能是横向扩展的端点)上处理,并且它要么立即失败(悲观锁定),要么在尝试保持状态时(乐观锁定)。将重试该消息。
这是正常行为,无法避免。然而,锁打开的时间越长,发生这种情况的可能性就越大。通常的建议是,除了业务流程的编排之外,永远不要做任何其他事情。因此,甚至不检索或存储您自己的业务数据。但是对于网络服务,您无法控制网络服务,并且在消息失败之前可能需要连接超时或更长的时间。相关消息会更快失败,并且它们很可能最终会出现在错误队列中。
除了编排业务流程和 'just' 发送消息之外,什么都不做就可以避免。保持对数据的锁定尽可能短。
除了 Dennis 的功能性回答外,我还觉得这里还有代码健康/代码架构方面的问题,尤其是关注点分离。 saga 的功能是 orcehstration - 建模 long-running 业务流程。我建议让 saga 调用一个方法进而调用 webservice 的成本非常低,并且代码健康状况的增加相对于成本来说很大。
换句话说,我建议编排是业务逻辑,因为调用 Web 服务更像是基础架构代码而不是业务逻辑。
这种区别很重要的原因有很多,但立即想到的一个是您的测试策略。您的基础设施代码测试策略可能与业务逻辑测试策略完全不同。当 class 两者兼而有之时,这很难做到。
在 NServiceBus documentation 中声明 sagas 不应调用 Web 服务:
Other than interacting with its own internal state, a saga should not access a database, call out to web services, or access other resources - neither directly nor indirectly by having such dependencies injected into it.
由于没有解释为什么不这样做,我想请社区帮助我解决这个问题。
我明白为什么我无法查询数据库:状态可能在发出事件和处理事件之间发生了变化。我不明白的部分是关于网络服务。
为什么说 POST 使用给定 ID 的 ShipOrder 命令发送 Web 服务是不好的做法?
通常最好在 https://discuss.particular.net/ 上或通过常规支持向特定软件团队本身提出此类问题。原因是这些问题相当开放,往往会产生一个回复线程。
既然我在为Particular Software工作,那我们就在这里继续吧。您可以随时复制 question/thread.
主要是saga状态可能存在的争用和一致性问题。根据持久性,saga 状态被检索并使用悲观或乐观锁定进行持久化。无论哪种方式,如果交易花费的时间太长,则可能会收到与同一传奇实例相关的另一条消息。它可能在不同的(并发)线程(或者可能是横向扩展的端点)上处理,并且它要么立即失败(悲观锁定),要么在尝试保持状态时(乐观锁定)。将重试该消息。
这是正常行为,无法避免。然而,锁打开的时间越长,发生这种情况的可能性就越大。通常的建议是,除了业务流程的编排之外,永远不要做任何其他事情。因此,甚至不检索或存储您自己的业务数据。但是对于网络服务,您无法控制网络服务,并且在消息失败之前可能需要连接超时或更长的时间。相关消息会更快失败,并且它们很可能最终会出现在错误队列中。
除了编排业务流程和 'just' 发送消息之外,什么都不做就可以避免。保持对数据的锁定尽可能短。
除了 Dennis 的功能性回答外,我还觉得这里还有代码健康/代码架构方面的问题,尤其是关注点分离。 saga 的功能是 orcehstration - 建模 long-running 业务流程。我建议让 saga 调用一个方法进而调用 webservice 的成本非常低,并且代码健康状况的增加相对于成本来说很大。
换句话说,我建议编排是业务逻辑,因为调用 Web 服务更像是基础架构代码而不是业务逻辑。
这种区别很重要的原因有很多,但立即想到的一个是您的测试策略。您的基础设施代码测试策略可能与业务逻辑测试策略完全不同。当 class 两者兼而有之时,这很难做到。