该系统有7个WCF服务,将增长到9个,每个都在一个单独的控制台app / windows服务中自托管.所有这些都是单实例和单线程.所有服务都具有相同的OperationContract:它们公开Register()和Send()方法.当客户端服务想要连接到另一个服务时,他们首先调用Register(),然后如果成功,他们将使用Send()进行所有其余的通信.我们有一个DataContract,它有一个枚举MessageType和一个Content Propety,它可以包含其他DataContract“payloads”.服务对消息的作用由枚举MessageType决定……一切都通过Send()方法传递,然后被路由到switch语句……我怀疑这是不寻常的
Register()和Send()实际上是OneWay和Async …服务的所有结果都由WCF CallbackContract返回给客户端服务.我相信使用CallbackContracts的共鸣是促进我们正在使用的发布 – 订阅模型.问题不是我们的所有通信都适合发布 – 订阅并且使用CallbackContracts意味着我们必须在返回的结果消息中包含源详细信息,以便客户端可以计算出最初返回的结果…再次客户端有一个switch语句来解决如何处理基于MessageType(以及其他嵌入的详细信息)从服务到达的消息.
在拓扑方面:服务在图中形成“节点”.每个服务都硬编码了它启动时必须连接的其他服务的列表,并且不允许客户端服务“注册”它,直到它完成所需的所有连接.例如,我们有一个LoggingService和一个DataAccessService. DataAccessSevice是LoggingService的客户端,因此DataAccess服务将在启动时尝试向LoggingService注册.直到它成功注册DataAccess服务将不允许任何客户端注册它.结果是,当系统整体启动时,服务以级联方式启动.我不认为这是一个问题,但这是不寻常的吗?
为了使事情变得更复杂,系统要求之一是服务或“节点”不需要彼此直接注册以便彼此发送消息,而是可以通过间接链接进行通信.例如,假设我们在链中连接了3个服务A,B和C,A可以通过B …使用2个跃点向C发送消息.
我实际上负责这个并编写了路由系统,这很有趣,但在我可以问为什么它真的需要之前,领先了.据我所知,没有理由不将服务直接连接到他们需要的其他服务.更重要的是我必须在所有事物之上编写可靠性系统,因为要求在系统中的节点之间进行可靠的消息传递,而通过简单的点对点链接,WCF可靠地完成工作.
在这个项目之前,我只使用winforms桌面应用程序3年,不知道更好.我的怀疑是这个项目过于复杂:我想总结一下,我的问题是:
1)图表拓扑的概念是否在间接链接上跳跃的消息不寻常?为什么不直接将服务连接到他们需要访问的服务(实际上我们正在做什么……我不认为我们有任何消息跳跃)?
2)在OperationContract中只暴露了2个方法,并使用MessageType枚举来确定消息是什么/如何处理异常? WCF服务不应该公开许多具有特定目的的方法,而客户端选择它想要调用哪些方法?
3)通过CallbackContracts进行的所有通信都回到了客户端.当然,同步或asyc请求响应更简单.
4)服务的概念是否不允许客户端服务连接到它(注册),直到它连接到它的所有服务(它是客户端)是一个合理的设计?我认为这是我同意的唯一设计方面,我的意思是DataAccessService在与日志服务建立连接之前不应接受客户端.
我有很多WCF问题,后面的主题会有更多问题.提前致谢.
同意,整个事情似乎有点奇怪.All of them are single instance and
single threaded.
这肯定会回来并导致巨大的性能问题 – 保证.我不明白为什么有人想要开始编写单例WCF服务(除了少数边缘情况,它确实有意义),如果你有单一的WCF服务,为了获得任何体面的性能,它必须是多线程的(这是一个棘手的编程,这就是为什么我几乎总是建议反对它).
All services have the same
OperationContract: they expose a
Register() and Send() method.
这也很奇怪.所以任何人先调用.Register(),然后用不同的参数多次调用.Send()?有趣的设计,真的…. SOA的假设是你将服务设计为你想要暴露给外部世界的一组功能的模型,例如:您的CustomerService可能具有GetCustomerByID,GetAllCustomersByCountry等方法 – 取决于您的需要.
只有一个Send()方法,其中包含定义正在执行的操作的参数,看起来有点……不寻常,不太直观/清晰.
Is this idea of a graph topology with
messages hopping over indirect links
unusual?
不必要.将单个接口暴露给外部世界是有意义的,然后使用一些内部后端服务来完成实际工作. .NET 4实际上将引入一个RoutingService in WCF,这使得这些场景更容易.我不认为这是一个很大的禁忌.
Is doing all communication back to a
client via CallbackContracts unusual.
是的,不寻常,脆弱,凌乱 – 如果你能做到没有它 – 去吧.如果你有大多数简单的调用,比如GetCustomerByID – 使它们成为标准的请求/响应调用 – 客户端请求某些东西(通过提供客户ID)并获取一个Customer对象作为返回值.简单得多!
如果您确实有长时间运行的服务调用,可能需要几分钟或更长时间才能完成 – 那么您可能会考虑将请求存入队列的单向调用,并且稍后会处理该请求.通常,在这里,您可以将答案存入客户端随后检查的响应队列中,或者您可以使用两种额外的服务方法来提供请求的状态(是否已完成?)以及第二种方法来检索该请求的结果.
希望有助于您入门!