3

我分别有三个 wcf 服务 A、B 和 C,因为我希望它是 SOA(面向服务的体系结构),我的设置工作方式是当我从客户端向服务器发送请求时。

  1. 所有服务都是自托管的 Windows 服务。
  2. 客户端向服务 A发送请求(客户端不知道其他服务 B 和 C);
  3. 服务 A 最终将该请求发送到服务 B 和服务 C。
  4. 服务 B 和 C 将响应发送回服务 A,该响应将由服务 A 发送回客户端。

我面临的问题:如果我对服务 B 的代码进行任何更改并重建并重新启动服务,我在获取响应时遇到问题,但是当我重新启动所有剩余的服务时它工作正常。

换句话说,我的客户不会得到响应,除非我重新启动所有服务(A、B 和 C),即使我只更改了一个服务中的代码并重新构建它。我知道如果我重新启动所有服务,事情就会起作用三个服务,但我想知道这是我设计方式中的问题,还是我必须处理自托管的 Windows 服务。所有服务(A、B、C)都是独立的,因为没有一个相互依赖。

有人曾在 SOA 中看到过这样的事情吗?如果有人能指导我找到适当的解决方案,我会很高兴吗?

4

2 回答 2

3
  1. 用任何类型的队列替换服务之间的 WCF(一个服务发布某些内容,另一个可以在它们准备好时读取)。可以是任何东西。可以是一个简单的表格,如果有新内容,您可以从中读取。可以是 RabbitMQ、NServiceBus 等,任何适合你的。

  2. 定义放入队列的消息:命令和事件。两者都是具有属性的简单类,没有逻辑。命令代表系统被要求执行的操作(RegisterUser、PlaceOrder 等),事件代表系统已完成的操作(UserRegistered、OrderApproved、PaymentReceived 等)。动作要明确,不要做类似“我已经更改了客户端上用户的所有属性,现在我调用 SaveUser(user)”之类的事情。您的服务应该知道如何更改对象,客户端应该只命令做什么

  3. 永远不要破坏你的合同。这很简单,比听起来更容易:您可以内容添加到您的消息合同中,但不能删除。换句话说,你只是保持你的合约向后兼容。

现在你有了一个更好的设计:服务只通过队列中的消息进行通信,消息是向后兼容的。这意味着您可以随时停止任何服务而不会影响其他服务:它们将继续将消息发送到队列中,并且当停止的服务再次返回时,它将赶上处理队列中的所有内容。

然后,如果您愿意,您可以对客户端交互使用相同的方法:如果客户端不调用 WCF,而只是将它们的命令放在某种队列中,那么服务升级或其他停机时间不会影响用户体验。

示例:如果我使用 WCF 下订单或将商品放入购物卡,那么如果出现问题或服务因维护而停止,我将无法执行此操作。我会单击一个按钮并遇到一个令人讨厌的错误。更重要的是我的订单不会进入系统。相反,如果中间有队列,我只将我的命令放入队列中。现在,即使我的服务目前处于关闭状态,或者遇到高负载(因此很慢),我的用户体验仍然是相同的并且不会降低。只是我的命令稍后会处理,但作为客户我并不在意。在这种情况下,我的订单不会丢失。系统变得容错和自平衡。

如果您只是将队列放在中间而不是遇到 WCF 带来的空间和时间耦合问题,那么您可以做各种奇妙的技巧 :) 而我所描述的只是开始...... :)

于 2013-02-22T13:31:36.217 回答
1

您可能需要考虑使用服务总线(例如NServiceBus)来帮助您完成功能。

它将帮助您解决的第一个问题是通过发布/订阅消息模式解耦您的服务。与其在一个或另一个服务中调用 Web 服务,不如发布事件以在发生某些事情时通知相应的服务。在您的情况下,这看起来像这样:

  1. 客户端调用服务 A 中的 Web 服务。
  2. 服务 A 发布消息“收到客户端命令”,服务 B 和 C 订阅该消息。
  3. 服务 B 和 C 处理此事件,然后发布自己的事件。
  4. 服务 A 订阅事件并回复客户端。

使用 NServiceBus 的第一个和直接的好处是可靠性。最重要的是,您可以轻松地对消息进行版本控制,而不会影响您的客户或您各自的服务。NServiceBus 具有完整的 WCF 集成,因此您的客户端可以像以前一样继续向您的服务发送消息。

使您的场景有趣的一件事是您无法保证服务 B 和 C 何时将其响应发送回您。在服务收到他们的响应之前,您是否保持与客户端的连接打开?在向客户端发送其响应之前,您是否需要两个响应?如果其中一项或一项服务崩溃会发生什么?如果在服务 A 收到响应之前您可以等待多长时间有时间限制怎么办?所有这些问题以及更多问题都可以通过 NServiceBus 中称为 Sagas 的功能来回答。一探究竟。

如果无法使用 NServiceBus,那么事情就会变得更加困难。WCF 不支持开箱即用的发布/订阅,因此您必须自己烘焙。至少我会建议使用它来解耦您的服务。如何管理服务中的状态和时间耦合是另一回事。为自己省去麻烦。

还有其他框架,但如果您想要以开发人员为中心、经济高效的方式来创建基于 .NET 的解决方案,那么建议使用 NServiceBus。

于 2013-02-20T05:57:25.393 回答