7

我正在考虑为一组服务提供 SOA 架构,以支持我咨询的业务,以前我们使用数据库集成,每个应用程序从共享的 MS SQL 数据库中挑选出它需要的内容并使用它等等。我们有各种与怪物数据库(包括 java、.net 和 microsoft access)集成的应用程序具有引用完整性,因为一切都紧密耦合。

我对如何支持服务之间的数据共享有点困惑。

让我们以产品服务为例,它位于批发商每月提供的产品数据库之上。我们建立了一个领域模型,并使用 Hibernate 或其他任何方式将其放在数据库中,实施明智的产品是一个大型对象图,给出了批发商提供的有关产品的信息。

现在假设 Review 服务、Pricing Service、Shipping Service 和 Stock Service 将订阅 ProductUpdated、ProductAdded、ProductDeleted。问题是每个服务只需要关于产品的部分或部分信息。运输可能只需要尺寸和重量。定价可能只需要产品 ID、批发成本、批量折扣、迄今为止有效的价格。审核可能需要产品 ID、产品名称、生产者。

仅发布整个产品(合适的非特定于订阅者的合同,例如 ProductUpdated 和合适的模式 - 代表所有产品对象图)并让订阅者将他们需要的任何内容映射到他们的域模型(或者做他们想做的事)是标准做法吗?想要,甚至可能没有域模型)...

或者当我写这篇文章时,我在想也许:

产品服务发布 ProductAdded 消息(不包括产品详细信息,仅包含产品 ID 和时间戳)

Pricing Service 订阅 ProductAdded 并发布 RequestPricingForProduct 消息

产品服务发布 ResultForPricingForProduct 消息

嗯..似乎好一点...但感觉就像我正在根据我可以识别的其他服务以及他们将需要什么来建立产品服务合同,也许将来 XYZ 服务需要不同的东西。我将停在那里,因为我认为我感到困惑的地方越来越清楚......也许上面的方法会起作用,因为我应该公开一种方法来返回应该公开的任何内容嗯嗯。

非常感谢任何意见或方向。对不起,如果这看起来半生不熟。

4

2 回答 2

5

我实际上认为这个问题的解决方案是不共享数据。SOA 意味着数据归服务所有——它是该数据的技术权威。我建议阅读一些 Pat Helland 的文章,例如Data On The Inside、Data On The Outside

唯一应该在这些不同服务之间共享的是主键 - 您示例中的 ProductId。否则,对于每个服务,需要在事务上保持一致的数据会放在一起。

不需要有一个“产品”。每项服务都可以对其服务中的产品有不同的看法。对于定价服务,您有一个 productId 和一个价格。对于评论服务,productId 和评论。等等。

这开始让人们感到困惑的是,如果这些数据来自所有这些不同的服务,如何在 UI 中显示这些数据。如何显示具有 ProductService 产品名称和 ReviewService 评论文本的产品的评论列表?

答案是从所有不同的服务中组合 UI。从产品服务中获取产品并从评论服务中获取评论数据,然后在 UI 中组合该数据。

于 2013-06-06T01:58:55.163 回答
3

我最近在你的位置。通过服务直接暴露底层对象的问题是增加了层之间的耦合,使用面向服务的架构根本没有意义。如果不影响 Web 服务,您将无法更改这些对象或业务规则。

听起来你在正确的轨道上。如果您认真对待分离层,那么最常见的模式是为 Web 服务(可能是每个服务)创建一组新的单独的消息类,并来回转换您的内部对象。

有关如何以这种方式设置服务层的示例,请参见“服务接口”模式。在服务的客户端,有一个相反的模式,称为“服务网关”。

应用程序架构指南 2.0 有一整章专门介绍您正在做出的决策类型(http://apparchguide.codeplex.com/Wiki/View.aspx?title=Chapter%2013%20-%20Service%20Layer%20Guidelines)。我会下载整个指南。

这是与您最相关的部分。长话短说,如果您花时间创建新的粗粒度方法和基于消息的对象,您最终会得到一个更好的 Web 服务:

设计服务接口时请考虑以下准则: 考虑使用粗粒度接口来批处理请求并最大限度地减少网络上的调用次数。以业务逻辑的更改不会影响接口的方式设计服务接口。不要在服务接口中实现业务规则。考虑使用参数的标准格式以提供与不同类型客户端的最大兼容性。不要在您的界面设计中对客户使用服务的方式做出假设。不要使用对象继承来实现服务接口的版本控制。

于 2009-06-10T02:20:12.147 回答