2013-02-19 288 views
3

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

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

问题IM被发送回客户端面临:如果我在服务B的代码进行任何更改并重建并重新启动服务,我有问题获取响应,但当我重新启动所有其余的服务,然后它工作正常。

换句话说,我的客户端没有得到响应,除非我重新启动所有的服务(A,B和C),即使我只是在一个服务中更改了代码并重新构建了它。我知道如果我重新启动所有三个服务,但我想知道这是我的设计方式的问题,或者这是我必须处理自我托管的Windows服务。所有的服务(A,B,C)是独立的,因为没有任何依赖彼此。

有没有人见过这样的事情发生在SOA中。我会很高兴,如果有人能指导我适当的解决方案?

+0

如果版本包括版本号,并将其存储在客户端上生成的代理,这可以解释为什么你要刷新/重建代理。 – 2013-02-19 21:50:59

+0

您应该记录并研究您声称拥有的问题。是否抛出异常?服务使用哪些绑定? – CodeCaster 2013-02-19 23:46:28

回答

3
  1. 用任何类型的队列替换服务之间的WCF(一个服务发布的东西,其他可以读取时,他们准备好了)。可以是任何东西。可以是一个简单的表格,如果有新的东西,你可以从中读取。可以是RabbitMQ,NServiceBus等,无论适用于您。

  2. 定义你把队列中的消息:命令和事件。两者都是具有属性的简单类,没有逻辑。命令表示系统要求做什么(RegisterUser,PlaceOrder等),事件表示系统已完成的操作(UserRegistered,OrderApproved,PaymentReceived等)。明确说明动作,不要做类似于“我已更改客户端上的所有用户属性,现在我调用SaveUser(用户)”的内容。 您的服务设知道如何改变的对象,客户只能指挥什么做。

  3. 永远不会破坏你的合同。这很容易,比听起来容易:您可以添加东西到您的消息合约,但无法删除。换句话说,你只需保持你的合同向后兼容。

现在你有一个更好的设计:服务只通过队列中的消息进行通信,消息是向后兼容的。这意味着您可以随时停止任何服务而不会影响其他服务:它们将继续将消息发送到队列中,并且当停止的服务再次返回时,它将赶上处理队列中的所有内容。然后,如果你愿意,你可以在客户端交互中使用相同的方法:如果不是调用WCF客户端,而只是将他们的命令置于某种队列中,那么服务升级或其他停机时间不会影响用户体验。

例子:如果我使用WCF来下订单或把项目变成购物卡,然后如果有问题或服务正在维护中,我将无法做到这一点。我会点击一个按钮,并有一个令人讨厌的错误。更重要的是,我的订单不会进入系统。 相比之下,如果中间有一个队列,我只会将我的命令放入队列中。现在,即使我的服务目前处于关闭状态,或者遇到高负载(因此速度较慢),那么我的用户体验仍然相同,并且不会降级。这只是我的命令将稍后处理,但作为客户我并不在乎。我的订单在这种情况下不会丢失。该系统变得容错和自我平衡。

如果您只是在中间放置一个队列,而不是遇到WCF附带的空间和时间耦合问题,您可以使用各种各样的奇妙技巧: 而我所描述的只是开始...... :)

1

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

它将帮助您解决的第一个问题是通过发布/订阅消息传递模式解耦您的服务。不是在一个或其他服务中调用Web服务,而是在发生事件时发布通知相应服务的事件。在你的情况,这将是这个样子:

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

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

让您的场景变得有趣的一件事是,您无法保证服务B和服务C何时将他们的回复发送给您。您是否保持与客户的连接处于打开状态,直到Service收到他们的回复?在您向客户发送回复之前,您是否需要两种回答?如果其中一项或其中一项服务崩溃会发生什么?如果在服务A收到回复之前有多久可以等待的时间限制?所有这些问题以及更多问题都可以通过NServiceBus中名为Sagas的功能来解决。一探究竟。

如果使用NServiceBus是不可能的事情变得更加困难。 WCF不支持发布/订阅,所以你将不得不自己烘焙。至少我会建议使用它来分离你的服务。如何管理服务中的状态和时间耦合是另一回事。省去麻烦。

还有其他的框架存在,但如果你想有一个开发中心,成本创造那么一个基于.NET解决方案建议使用NServiceBus有效途径。