C# WCF服务依赖项

C# WCF服务依赖项,c#,wcf,soa,C#,Wcf,Soa,我分别有三个wcf服务A、B和C,因为我希望它是SOA(面向服务的体系结构),我的设置工作方式是当我从客户端向服务器发送请求时 所有服务都是自托管windows服务 客户端向服务A发送请求(客户端对其他服务B和C没有任何线索) 服务A最终将该请求发送给服务B和服务C 服务B和C将响应发送回服务A,服务A将响应发送回客户端 我面临的问题:如果我对服务B的代码进行了任何更改,并重新构建和重新启动了服务,我在返回响应时遇到了问题,但当我重新启动所有剩余的服务时,它就可以正常工作 换句话说,除非我重新启

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

  • 所有服务都是自托管windows服务
  • 客户端向服务A发送请求(客户端对其他服务B和C没有任何线索)
  • 服务A最终将该请求发送给服务B和服务C
  • 服务B和C将响应发送回服务A,服务A将响应发送回客户端
  • 我面临的问题:如果我对服务B的代码进行了任何更改,并重新构建和重新启动了服务,我在返回响应时遇到了问题,但当我重新启动所有剩余的服务时,它就可以正常工作

    换句话说,除非我重新启动所有服务(A、B和C),否则我的客户端不会得到响应尽管我只是在一个服务中更改了代码并重新构建了它。我知道如果我重新启动所有三个服务,事情会成功,但我想知道这是我设计的问题,还是我必须处理自托管的windows服务。所有服务(A、B、C)都是独立的,因为它们互不依赖


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

    < P>你可能想考虑使用一个服务总线来帮助你完成你的功能。 它将帮助您解决的第一个问题是通过发布/订阅消息传递模式实现服务的解耦。与其在一个或另一个服务中调用web服务,不如发布事件,在发生事件时通知相应的服务。在您的情况下,这看起来像这样:

  • 客户端调用服务A中的web服务
  • 服务A发布服务B和C订阅的“客户端命令已接收”消息
  • 服务B和C处理此事件,然后发布它们自己的事件
  • 服务A订阅事件并回复客户端
  • 使用NServiceBus的第一个也是最直接的好处是可靠性。除此之外,您还可以轻松地对邮件进行版本设置,而不会影响您的客户或您各自的服务。NServiceBus具有完整的WCF集成,因此您的客户端可以像以前一样继续向您的服务发送消息

    让您的场景变得有趣的一点是,您无法保证服务B和C何时向您发送响应。在服务收到响应之前,您是否保持与客户端的连接处于打开状态?在向客户端发送响应之前,是否需要这两个响应?如果其中一个或其中一个服务崩溃,会发生什么情况?如果在服务接收到响应之前您可以等待的时间有限制,该怎么办?所有这些问题以及更多问题都可以通过NServiceBus中名为Sagas的功能得到解答。看看吧

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

    还有其他框架,但如果您希望以开发人员为中心,以经济高效的方式创建基于.NET的解决方案,则建议使用NServiceBus

  • 将服务之间的WCF替换为任何类型的队列(一个服务发布某些内容,另一个可以在准备就绪时读取)。什么都可以。可以是一个简单的表格,如果有新内容,您可以在其中阅读。可以是RabbitMQ、NServiceBus等任何适合您的工具

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

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

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

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

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

    如果你只是在中间放置一个队列,而不是遇到空间问题,那么你可以做各种奇妙的把戏。