wcf - SOA 和 WCF 设计问题 : Is this an unusual system design?

标签 wcf soa

我发现自己负责继续开发一个不是我最初设计的系统,并且不能问最初的设计师为什么要做出某些设计决定,因为他们已经不在了。我是一个设计问题的初级开发人员,所以当我开始这个项目时我真的不知道该问什么,这是我的第一个 SOA/WCF 项目。

该系统有 7 个 WCF 服务,将增长到 9 个,每个服务都自托管在单独的控制台应用程序/Windows 服务中。它们都是单实例和单线程的。所有服务都具有相同的 OperationContract:它们公开了 Register() 和 Send() 方法。当客户端服务想要连接到另一个服务时,它们首先调用 Register(),然后如果成功,它们将使用 Send() 完成所有其余的通信。我们有一个 DataContract,它有一个枚举 MessageType 和一个 Content 属性,它可以包含其他 DataContract“有效负载”。服务对消息的处理由枚举 MessageType 决定......一切都通过 Send() 方法,然后路由到 switch 语句......我怀疑这是不寻常的

Register() 和 Send() 实际上是 OneWay 和 Async...服务的所有结果都通过 WCF CallbackContract 返回给客户端服务。我相信使用 CallbackContracts 的原因是为了促进我们正在使用的 Publish-Subscribe 模型。问题不是我们所有的通信都适合发布订阅,并且使用 CallbackContracts 意味着我们必须在返回的结果消息中包含源详细信息,以便客户端可以计算出返回的结果最初是为了什么......再次客户端有一个 switch 语句来计算如何处理来自基于 MessageType(和其他嵌入详细信息)的服务的消息。

在拓扑方面:服务在图中形成“节点”。每个服务都硬编码了它在启动时必须连接的其他服务的列表,并且在建立了它需要的所有连接之前不允许客户端服务向它“注册”。例如,我们有一个 LoggingService 和一个 DataAccessService。 DataAccessSevice 是 LoggingService 的客户端,因此 DataAccess 服务将在启动时尝试向 LoggingService 注册。在它可以成功注册之前,DataAccess 服务将不允许任何客户端向其注册。结果是,当系统作为一个整体启动时,服务以级联方式启动。我不认为这是一个问题,但这不寻常吗?

更复杂的是,系统要求之一是服务或“节点”不需要为了相互发送消息而直接相互注册,而是可以通过间接链接进行通信。例如,假设我们有 3 个服务 A、B 和 C 连接在一个链中,A 可以通过 B 向 C 发送消息......使用 2 跳。

我实际上负责这个任务并编写了路由系统,这很有趣,但是在我问为什么真的需要它之前,领导就离开了。据我所知,服务没有理由不能直接连接到他们需要的其他服务。更重要的是,我必须在所有内容之上编写一个可靠性系统,因为要求在系统中的节点之间具有可靠的消息传递,而 WCF 可以通过简单的点对点链接可靠地完成这项工作。

在这个项目之前,我只在 winforms 桌面应用程序上工作了 3 年,不知道更好。我怀疑这个项目的事情过于复杂:我想总结一下,我的问题是:

1) 消息在间接链接上跳跃的图拓扑的想法不寻常吗?为什么不直接将服务连接到他们需要访问的服务(这实际上是我们所做的......我认为我们没有任何消息跳跃)?

2) 在 OperationContract 中只公开 2 个方法并使用 MessageType 枚举来确定消息的用途/如何处理它是不寻常的吗? WCF 服务不应该公开许多具有特定用途的方法,而客户端选择它想要调用的方法吗?

3) 是否通过 CallbackContracts 将所有通信返回给客户端异常。当然同步或异步请求响应更简单。

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?



不必要。只向外界公开一个接口(interface),然后使用一些内部后端服务来完成实际工作是有意义的。 .NET 4 实际上会引入一个 RoutingService in WCF这使得这些场景更容易。我不认为这是一个很大的禁忌。

Is doing all communication back to a client via CallbackContracts unusual.



是的,不寻常的、脆弱的、凌乱的——如果你可以没有它——去吧。如果您的电话大多是简单的,例如 GetCustomerByID - 使它们成为标准的请求/响应调用 - 客户端请求某些内容(通过提供客户 ID)并返回 Customer对象作为返回值。简单多了!

如果您确实有长时间运行的服务调用,这可能需要几分钟或更长时间才能完成 - 那么您可以考虑单向调用,它只是将请求存入队列,然后该请求得到处理。通常,在这里,您可以将答案存入客户端然后检查的响应队列中,或者您可以使用两个额外的服务方法来为您提供请求的状态(是否已完成?)和第二个方法来检索请求该请求的结果。

希望能帮助您入门!

关于wcf - SOA 和 WCF 设计问题 : Is this an unusual system design?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2277662/

相关文章:

c# - 将 X.509 证书发送到 WCF c#

java - 从表示层调用服务层

c# - 使用 .Net Standard 2.0 库中的 x509 证书使用 WCF Web 服务?

soa - 帮助经理和客户了解 SOA

web-services - 简单的SOAP客户端(例如用于Linux的SOA测试工具)?

java - 检查 Oracle BPEL 轮询数据库适配器是否正在工作

web-services - 如何在外部 WS-policy 附件文件中指定服务实例?

c# - 使用 KSOAP2 从 Android 向 WCF 发送数据

WCF 跟踪 (svclog) 间歇性停止。回收AppPool后启动

c# - 使用 RX 观察 WCF 服务调用