我正在考虑使用一组服务的SOA架构来支持我正在咨询的业务,以前我们使用数据库集成,其中每个应用程序从共享的MS SQL数据库中选择它需要的内容并使用它等。我们有各种应用程序与怪物数据库集成,包括java,.net和microsoft访问,有参考完整性,因为一切都紧密耦合。
我对如何支持服务之间的数据共享感到困惑。
让我们将产品服务放在批发商每个月提供的产品数据库之上。我们构建了一个域模型,并将其放在数据库中,使用Hibernate或者更多,实现明智产品是一个大型对象图,给出了批发商提供的有关产品的信息。
现在我们可以说,评论服务,定价服务,送货服务和库存服务将订阅ProductUpdated,ProductAdded,ProductDeleted。问题是每个服务只需要有关产品的部分或部分信息。运输可能只需要尺寸和重量。定价可能只需要产品ID,批发成本,批量折扣,迄今为止有效的价格。审核可能需要产品ID,产品名称,生产商。
标准做法是发布整个产品(适当的非订户特定合同,例如ProductUpdated,以及合适的架构 - 代表所有产品对象图),让订户将他们需要的任何内容映射到他们的域模型(或者heck)做他们想要的,甚至可能没有域模型)...
或者当我写这篇文章时我想的可能是:
产品服务发布ProductAdded消息(不包括产品详细信息,只是产品ID和时间戳)
定价服务订阅ProductAdded并发布RequestPricingForProduct消息
产品服务发布ResultForPricingForProduct消息
嗯......看起来好一点......但感觉就像我正在建立产品服务合同,基于我可以识别的其他服务以及他们将需要什么,也许在未来的XYZ服务需要不同的东西。我会停在那里,因为我认为它变得越来越清楚,我感到困惑...或许上述方法将起作用,因为我应该揭露一种方式来返回任何应该是公共的正确的。任何评论或方向都非常感谢。对不起,如果这出现了一半。
答案 0 :(得分:5)
我实际上认为这个问题的解决方案是不共享数据。 SOA意味着数据由服务拥有 - 它是该数据的技术权威。我建议阅读一些Pat Helland文章,例如Data On The Inside, Data On The Outside。
这些不同服务之间唯一应该共享的是主键 - 示例中的ProductId。否则,对于每个服务,需要在事务上保持一致的数据会一起使用。
不需要一个“产品”。每项服务可以在其服务中具有不同的产品视图。对于定价服务,您有productId和价格。对于审核服务,productId和审核。等等。
如果这些数据开始让人感到困惑,那么如果来自所有这些不同的服务,那么如何在UI中显示这些数据。如何显示具有ProductService产品名称和ReviewService评论文本的产品的评论列表?
答案是从所有不同的服务组成UI。从产品服务获取产品并从审阅服务获取审阅数据,然后在UI中合并这些数据。
答案 1 :(得分:3)
我最近在你的位置。直接通过服务公开底层对象的问题是你增加了层之间的耦合,并且根本没有使用面向服务的架构。在不影响Web服务的情况下,您将无法更改这些对象或业务规则。
听起来你走在正确的轨道上。如果您认真考虑分层,那么最常见的模式是为Web服务(可能是每个服务)创建一组新的独立消息类,并来回转换内部对象。
有关如何以此方式设置服务层的示例,请参阅“服务接口”模式。在服务的客户端,有一种称为“服务网关”的相反模式。
“应用程序架构指南2.0”有一整章专门介绍您正在做出的决策类型(http://apparchguide.codeplex.com/Wiki/View.aspx?title=Chapter%2013%20-%20Service%20Layer%20Guidelines)。我会下载整个指南。
以下是与您最相关的部分。简而言之,如果你花时间创建新的粗粒度方法和基于消息的对象,你最终会得到一个更好的Web服务:
在设计服务界面时,请考虑以下准则: 考虑使用粗粒度接口批量请求并最小化网络上的呼叫数量。 以这样的方式设计服务接口,即对业务逻辑的更改不会影响接口。 不要在服务接口中实现业务规则。 考虑使用参数的标准格式以提供与不同类型的客户端的最大兼容性。 不要在界面设计中假设客户端使用服务的方式。 不要使用对象继承来实现服务接口的版本控制。