SOA 和 WCF 设计问题:这是一个不寻常的系统设计吗? [英] SOA and WCF design questions: Is this an unusual system design?

查看:24
本文介绍了SOA 和 WCF 设计问题:这是一个不寻常的系统设计吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have found myself responsible for carrying on the development of a system which I did not originally design and can't ask the original designers why certain design decisions were taken, as they are no longer here. I am a junior developer on design issues so didn't really know what to ask when I started on the project which was my first SOA / WCF project.

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

The system has 7 WCF services, will grow to 9, each self-hosted in a seperate console app/windows service. All of them are single instance and single threaded. All services have the same OperationContract: they expose a Register() and Send() method. When client services want to connect to another service, they first call Register(), then if successful they do all the rest of their communication with Send(). We have a DataContract that has an enum MessageType and a Content propety which can contain other DataContract "payloads." What the service does with the message is determined by the enum MessageType...everything comes through the Send() method and then gets routed to a switch statement...I suspect this is unusual

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

Register() and Send() are actually OneWay and Async...ALL results from services are returned to client services by a WCF CallbackContract. I believe that the reson for using CallbackContracts is to facilitate the Publish-Subscribe model we are using. The problem is not all of our communication fits publish-subscribe and using CallbackContracts means we have to include source details in returned result messages so clients can work out what the returned results were originally for...again clients have a switch statements to work out what to do with messages arriving from services based on the MessageType (and other embedded details).

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

In terms of topology: the services form "nodes" in a graph. Each service has hardcoded a list of other services it must connect to when it starts, and wont allow client services to "Register" with it until is has made all of the connections it needs. As an example, we have a LoggingService and a DataAccessService. The DataAccessSevice is a client of the LoggingService and so the DataAccess service will attempt to Register with the LoggingService when it starts. Until it can successfully Register the DataAccess service will not allow any clients to Register with it. The result is that when the system is fired up as a whole the services start up in a cascadeing manner. I don't see this as an issue, but is this unusual?

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

To make matters more complex, one of the systems requirements is that services or "nodes" do not need to be directly registered with one another in order to send messages to one another, but can communicate via indirect links. For example, say we have 3 services A, B and C connected in a chain, A can send a message to C via B...using 2 hops.

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

I was actually tasked with this and wrote the routing system, it was fun, but the lead left before I could ask why it was really needed. As far as I can see, there is no reason why services cannot just connect direct to the other services they need. Whats more I had to write a reliability system on top of everything as the requirement was to have reliable messaging across nodes in the system, wheras with simple point-to-point links WCF reliabily does the job.

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

Prior to this project I had only worked on winforms desktop apps for 3 years, do didn't know any better. My suspicions are things are overcomplicated with this project: I guess to summarise, my questions are:

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

1) Is this idea of a graph topology with messages hopping over indirect links unusual? Why not just connect services directly to the services that they need to access (which in reality is what we do anyway...I dont think we have any messages hopping)?

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

2) Is exposing just 2 methods in the OperationContract and using the a MessageType enum to determine what the message is for/what to do with it unusual? Shouldnt a WCF service expose lots of methods with specific purposes instead and the client chooses what methods it wants to call?

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

3) Is doing all communication back to a client via CallbackContracts unusual. Surely sync or asyc request-response is simpler.

4) 服务在连接到它的所有服务(它是一个客户端)之前不允许客户端服务连接到它(注册)的想法是一个合理的设计吗?我认为这是我唯一同意的设计方面,我的意思是 DataAccessService 在与日志记录服务建立连接之前不应接受客户端.

4) Is the idea of a service not allowing client services to connect to it (Register) until it has connected to all of its services (to which it is a client) a sound design? I think this is the only design aspect I agree with, I mean the DataAccessService should not accept clients until it has a connection with the logging service.

我有很多 WCF 问题,更多问题将在以后的主题中提出.提前致谢.

I have so many WCF questions, more will come in later threads. Thanks in advance.

推荐答案

好吧,整个事情看起来有点奇怪,同意.

Well, the whole things seems a bit odd, agreed.

它们都是单实例并且单线程.

All of them are single instance and single threaded.

这肯定会回来并导致大量的性能问题 - 保证.我不明白为什么有人想要开始编写一个单例 WCF 服务(除了一些边缘情况,它确实有意义),如果你有一个单例 WCF 服务,为了获得任何体面的性能,它必须是多线程的(这是一种棘手的编程,这也是为什么我几乎总是反对它的原因).

That's definitely going to come back and cause massive performance headaches - guaranteed. I don't understand why anyone would want to write a singleton WCF service to begin with (except for a few edge cases, where it does make sense), and if you do have a singleton WCF service, to get any decent performance, it must be multi-threaded (which is tricky programming, and is why I almost always advise against it).

所有服务都有相同的OperationContract:他们公开了一个Register() 和 Send() 方法.

All services have the same OperationContract: they expose a Register() and Send() method.

这也很奇怪.所以任何人都会先调用.Register(),然后用不同的参数多次调用.Send()??有趣的设计,真的...... SOA 假设是你将你的服务设计成你想要暴露给外界的一组功能的模型,例如您的 CustomerService 可能有诸如 GetCustomerByIDGetAllCustomersByCountry 等方法 - 取决于您的需要.

That's rather odd, too. So anyone calling will first .Register(), and then call .Send() with different parameters several times?? Funny design, really.... The SOA assumption is that you design your services to be the model of a set of functionality you want to expose to the outside world, e.g. your CustomerService might have methods like GetCustomerByID, GetAllCustomersByCountry, etc. methods - depending on what you need.

只有一个带有定义正在执行的操作的参数的 Send() 方法似乎有点……不寻常且不是很直观/清晰.

Having just a single Send() method with parameters which define what is being done seems a bit.... unusual and not very intuitive / clear.

这是图拓扑的想法吗?在间接链接上跳跃的消息不寻常?

Is this idea of a graph topology with messages hopping over indirect links unusual?

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

Not necessarily. It can make sense to expose just a single interface to the outside world, and then use some internal backend services to do the actual work. .NET 4 will actually introduce a RoutingService in WCF which makes these kind of scenarios easier. I don't think this is a big no-no.

是否正在将所有通信返回给一个客户端通过 CallbackContracts 异常.

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

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

Yes, unusual, fragile, messy - if you can ever do without it - go for it. If you have mostly simple calls, like GetCustomerByID - make those a standard Request/Response call - the client requests something (by supplying a Customer ID) and gets back a Customer object as a return value. Much much simpler!

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

If you do have long-running service calls, that might take minutes or more to complete - then you might consider One-Way calls which just deposit a request into a queue, and that request gets handled later on. Typically, here, you can either deposit the answer into a response queue which the client then checks, or you can have two additional service methods which give you the status of a request (is it done yet?) and a second method to retrieve the result(s) of that request.

希望对您有所帮助!

这篇关于SOA 和 WCF 设计问题:这是一个不寻常的系统设计吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆