我发现自己有责任继续开发一个我最初没有设计过的系统,并且无法向原设计师询问为什么会采取某些设计决策,因为它们不再存在.我是设计问题的初级开发人员,所以当我开始我的第一个SOA/WCF项目的项目时,我真的不知道该问什么.
该系统有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发送消息.
我实际上负责这个并编写了路由系统,这很有趣,但在我可以问为什么它真的需要之前,领先了.据我所知,没有理由不将服务直接连接到他们需要的其他服务.什么是更多我不得不写一个可靠的系统上的一切之上的要求是有可靠消息跨节点系统,wheras简单点至点链接WCF reliabily做这项工作.
在这个项目之前,我只使用winforms桌面应用程序3年,不知道更好.我的怀疑是这个项目过于复杂:我想总结一下,我的问题是:
1)图表拓扑的概念是否在间接链接上跳跃的消息不寻常?为什么不直接将服务连接到他们需要访问的服务(实际上我们正在做什么......我不认为我们有任何消息跳跃)?
2)在OperationContract中只暴露了2个方法,并使用MessageType枚举来确定消息是什么/如何处理异常?WCF服务不应该公开许多具有特定目的的方法,而客户端选择它想要调用哪些方法?
3)通过CallbackContracts进行的所有通信都回到了客户端.当然,同步或asyc请求响应更简单.
4)服务的概念是否不允许客户端服务连接到它(注册),直到它连接到它的所有服务(它是客户端)是一个合理的设计?我认为这是我同意的唯一设计方面,我的意思是DataAccessService在与日志服务建立连接之前不应接受客户端.
我有很多WCF问题,后面的主题会有更多问题.提前致谢.
同意,整个事情似乎有点奇怪.
所有这些都是单实例和单线程.
这肯定会回来并导致巨大的性能问题 - 保证.我不明白为什么有人想要开始编写单例WCF服务(除了少数边缘情况,它确实有意义),如果你有单一的WCF服务,为了获得任何体面的性能,它必须是多线程的(这是一个棘手的编程,这就是为什么我几乎总是建议反对它).
所有服务都具有相同的OperationContract:它们公开Register()和Send()方法.
这也很奇怪.所以任何人先调用.Register(),然后用不同的参数多次调用.Send()?有趣的设计,真的....而SOA的假设是,你设计你的服务,是你希望暴露给外界的功能集合的模式,如您CustomerService可能有类似的方法GetCustomerByID,GetAllCustomersByCountry等等方法-取决于什么你需要.
只有一个Send()方法,其中包含定义正在执行的操作的参数,看起来有点......不寻常,不太直观/清晰.
这种图形拓扑的概念是否在间接链接上跳跃的消息不寻常?
不必要.将单个接口暴露给外部世界是有意义的,然后使用一些内部后端服务来完成实际工作..NET 4实际上将在WCF中引入RoutingService,这使得这种场景更容易.我不认为这是一个很大的禁忌.
通过CallbackContracts进行的所有通信都回到了客户端.
是的,不寻常,脆弱,凌乱 - 如果你能做到没有它 - 去吧.如果你有大多数简单的调用,比如GetCustomerByID- 使那些标准的请求/响应调用 - 客户端请求某些东西(通过提供客户ID)并获取一个Customer对象作为返回值.简单得多!
如果您确实有长时间运行的服务调用,可能需要几分钟或更长时间才能完成 - 那么您可能会考虑将请求存入队列的单向调用,并且稍后会处理该请求.通常,在这里,您可以将答案存入客户端随后检查的响应队列中,或者您可以使用两种额外的服务方法来提供请求的状态(是否已完成?)以及第二种方法来检索该请求的结果.
希望有助于您入门!
所有服务都具有相同的OperationContract:它们公开Register()和Send()方法.
您的设计在某些部分看起来很不寻常,只能进行两次操作.我没有使用过WCF,我们使用Java.但根据我的理解,Web服务的整个目的是公开您的合作伙伴可以使用的操作.
只有两个操作对我来说看起来像奇怪的设计.您通常使用WSDL公开您的API.在这种情况下,除非您有大量文档,否则WSDL不会给合作伙伴带来任何价值.通常,操作名称应该是不言自明的.目前,没有内部知识,合作伙伴不能使用您的系统.
通过CallbackContracts进行的所有通信都回到了客户端.当然,同步或asyc请求响应更简单.
同意您.异步应仅用于长时间运行的进程.Async增加了相关的开销.
| 归档时间: |
|
| 查看次数: |
616 次 |
| 最近记录: |