内容


首选数据源模式的深入研究

使用这种 SOA 规范将多个数据源描述为一个实体

Comments

价值主张和背景

首选数据源模式、或者首选源模式,是用于进行服务聚合的一种微流模式。该模式允许客户端从一组信息源检索信息,而无需了解(至少在较高的抽象级别上)多个源的存在。

考虑下面的情况,其中多个数据源必须作为一个数据源出现:

  • 某个公司有多个信息源,访问其中的某些信息源比访问其他的信息源(例如,本地局部数据库和远程局部数据库)需要付出更大的代价。
  • 公司可以升级它的 IT 系统,并且在升级的过程中,将会引入新的信息源,而这些新的信息源必须与旧的信息源(例如,客户信息源)协同使用。
  • 一个或者多个类似的业务可以进行合并,并且所有的业务在表现相同的实体(如客户)时,可能会存在一些不同的数据。
  • 任何单独的实体都有某个企业唯一的标识符,该标识符(例如,客户编号或者 SKU)是记录的一部分。

在 SOA Web 服务环境中,假定在信息管理环境中综合了以上的场景。

问题

客户端如何从一组不同的信息源中检索信息,而无需了解多个源的存在呢?

解决方案

首选数据源模式将这些数据源中的一个识别为首选数据源,而其他的则作为备用数据源,并且仅当首选数据源不能提供所需的信息时,才使用这些备用数据源。图 1 显示了 facade 和适配器之间的关系。

图 1. facade 和适配器的关系
facade 和适配器的关系

该模式假定从任何源所获得的信息都以描述实体的记录 的形式出现,如客户或零部件。此外,它还假定任何单独的实体都具有某个企业唯一的标识符,该标识符(例如,客户的编号或者 SKU)是记录的一部分。

该模式包含一个 facade,而这个 facade 中隐藏了多个信息源存在的事实,客户端只需要与这个 facade 进行交互。这个 facade 接口与首选源的接口相匹配,并且首选的接口中包含一个或多个操作,这些操作允许客户端查找(读取)匹配各种标准的信息。查找操作将返回匹配标准的 0 到 n 条记录。

值得注意的是,无论由哪个信息源提供信息,返回的信息中可能没有一条是所需的记录。可以考虑这样的场景,在该场景中,一个商店职员在全国范围的公司数据库中搜索名叫 John Smith 的客户。这项查找操作可能返回 20 个 John Smiths,但是其中可能没有任何一条记录对应于正站在这个职员前面的 John Smith。客户端必须依靠与用户之间的附加交互,以确定返回的这些记录中是否有所需的记录。

首选源模式假定一个信息源有一个或者多个查找操作,这些查找操作返回零个或多个实体记录的实例,或者可能是实体记录的一个子集。信息源可能有一个或者多个写操作,这些写操作允许客户端创建和更新实体记录。

查找操作

图 2 显示了该模式中查找操作的序列关系图。客户端调用 facade,然后 facade 调用首选的信息源。如果这个源不提供任何匹配的结果,那么 facade 将按照预定义的顺序调用其他备用的信息源,直到找到匹配的结果、或者直到它查找完所有可供选择的信息源。在它找到一个匹配结果或者查找完所有的信息源后,facade 会将结果返回到客户端。注意:为了清楚地进行描述,我们没有显示同步返回。

图 2. 查找操作
查找操作
查找操作

在最简单的形式中,首选源及其对应的模式仅支持查找(读取)操作。虚拟目录功能可以利用这种只读的模式,因为它不需要(或者可能没有能力)更新首选信息源。

对最简单形式的描述必须包括 Web 服务描述语言(WSDL)文档,该文档描述了首选信息源和所有备用信息源。facade 和所有备用源都使用首选源的接口(端口类型)。如果一个备用源没有在本地公开相同的接口,那么您可以对这个源应用转换模式,然而对这个模式的讨论超出了本文的范围。备用源的 WSDL 必须区别于首选源,至少在端点地址上有所区别,它在绑定方面需要进行更多的工作,这一点也不相同。该接口使用了描述实体记录的模式和任何其他的参数。注意:WSDL 文档将定义或导入该模式。

如前所示,假定实体记录包括唯一的 ID。您可以为将要应用这个模式的查找操作创建标识。将所有其他的操作作为传递(pass-through)操作处理。然后创建一个显示调用备用源顺序的列表。当然,对于这些服务,可以有单独的 WSDL 文档的列表;该列表中的第一项是首选源。

在更为一般的情况下,首选源接口可能包含附加的操作,这些操作允许客户端创建、更新、或者删除(在某些情况下,删除操作可能是无效的)。很明显,模式 facade 也必须支持这些附加的操作。

当读取操作的结果信息不是来自首选源时,您可能需要将该信息添加到首选源。该模式应该支持对首选源的高效更新,但是这可能会带来问题。可以考虑这样的客户信息场景:如果首选源(本地存储数据库)中没有所需的客户记录,那么它可能位于商店的某个遗留数据库中,或者在企业中没有对其进行定义,而您必须使用一个外部的信息源,如 Acxiom,它可以根据电话号码查找相应的信息。

facade 的活动依赖于从源返回的实体记录中的 ID。实际的备用源可能提供有效的 ID、无效的 ID、或者不提供 ID。有效的 ID 可以作为首选源中的 ID 接受。假定 facade 在遗留数据库中查找信息,并且有四条记录匹配搜索标准。进一步假定所有的记录都具有有效的 ID。在这个示例中,facade 应该根据具体的情况,不添加、添加一条、或者添加所有的四条记录到首选源。如果这些记录中没有一条是描述站在这个职员面前的顾客的,那么显然 facade 将不会在首选源中保存这些记录。如果其中有一条记录的确 描述了站在这个职员面前的人,那么 facade 很可能应该将该记录保存到首选源中。但是,您应该在什么时候进行这项操作呢?

当然,facade 没有办法知道哪条记录是正确的,所以客户端必须发起创建或者更新(写)操作。然而在这个示例中,如果没有关于该客户的新信息,那么客户端可能根本不执行任何写操作!最好的情况下,客户端可能进行了某些操作,比如写入一个新的时间戳,以表示对所标识客户的最后一次访问时间。如果在首选源和一个或者多个备用源之间存在迁移关系,那么您可能希望自动地从备用源中将所有的记录添加到首选源,而无需在客户端进行任何具体的操作。在迁移场景中,遗留源可能包含这样的实体记录,在企业的其他部分中引用了这些记录的 ID。因此,当您将遗留记录放入到首选源中时,您应该使用相同的 ID,以保持引用的完整性。要完成这项任务,需要有一项操作能够使用现有的 ID 来创建实体记录。

当来自备用源的匹配记录不包含有效的 ID 或者没有 ID时,您可能需要进行一组不同的操作,对于外部源,如 Acxiom,便是这种情况。如果这些记录没有 ID,并返回给了客户端,那么客户端可以简单地确定是否必须在首选源中创建一个匹配站在职员面前的人的记录,而无需来自 facade 的帮助。客户端可以使用一项操作(创建无 ID 的实体记录)将该记录添加到首选源(当然是通过 facade),您可以假定模式中必须存在这样的操作。如果返回的记录包含无效的 ID,并且返回给了客户端,那么客户端不能简单地确定是否必须在首选源中创建一个匹配站在职员面前的人的记录。事实上,提供客户端无效 ID 的想法似乎是不正确的。因为客户端无法检测出 ID 是无效的,所以它可以在另一个上下文中使用这个 ID 以链接实体记录。这意味着,facade 所使用的备用源必须返回有效的 ID 或者不返回 ID。如果实际的信息源无法做到这一点,那么您可能需要在转换模式包装器中产生有效的 ID 或者根本不产生 ID。创建有效的 ID 可能需要某些种类的 ID 关联服务,而它们允许您在多个环境中创建有效的 ID,但是该内容超出了这个模式的范围。

为 ID 创建服务或者函数(facade 可以调用该函数创建有效的 ID)定义服务提供者接口,这可能是很有趣的。在备用源不提供 ID 并且没有返回新插入记录的 ID 的创建方法的情况下,facade 可以使用该服务。在稍后描述的写策略中,这可能更加重要。该策略重点需要:

  • 在实体记录中标识 ID 字段。
  • 了解备用源是否提供有效的 ID 或者不提供 ID。

这些信息可以帮助驱动 facade 在各种情况下都可以采取的操作。查找和更新操作之间关系的另一个重要方面是,从查找操作返回的值类型、以及用于驱动创建操作的值类型的特征。当前的考虑是,模式的初始实现需要值类型始终等于实体记录。这消除了为如何标识实体记录的子集而增加附加信息的需要,并且使得映射代码实现最小化。

更新的主题产生了对每个备用源策略的需求,用于处理向首选源进行的写(创建或者更新)操作与从备用源读取(查找)操作返回的实体记录之间的关系。要驱动每个备用源的策略,您必须在首选源接口中标识查找、创建、和更新操作。接下来的部分描述了其中的部分策略。

无操作策略

为进行查找操作,facade 仅返回实体记录,而不为写操作进行任何工作。客户端必须检测 ID 的有效性,以推断出什么时候需要 create 操作,以便向首选源中插入记录,以及在 facade 上显式地调用创建操作。而由 facade 在首选源上调用创建操作。(请参见图 3)。

图 3. 无操作策略
无操作策略
无操作策略

当备用源不提供 ID 时,这可能是最好的策略。为了实现这个策略,简单地将所有的读操作传递到源,并返回结果。将所有其他操作传递到首选源。

添加所有内容的策略

作为查找操作的副作用,facade 将所有的实体记录添加到首选源。当记录来自首选源时,客户端的工作方式与它完全相同。有两种子策略:

  • 实体记录包含有效的 ID。
  • 实体记录不包含有效的 ID(或者没有 ID)。

对于第一种子策略(有效的 ID),facade 使用标识为 create_withID 的操作在首选源中创建相应的记录,并从备用源将这些记录返回给客户端。要使这个子策略生效,首选源必须支持允许现有的 ID 的创建操作。

对于第二种子策略(无 ID),facade 使用标识为 create_noID 的操作在首选源中创建相应的记录。为了防止执行附加的读取操作,facade 将首选源创建的 ID 放入到从备用源获得的记录中,随后将其返回给客户端。要使这个子策略生效,首选源必须支持返回 ID 作为首选源创建操作结果的创建操作(请参见图 4)。

图 4. 添加所有内容的策略
添加所有内容的策略
添加所有内容的策略

另外,如果不存在这样的操作,那么您可以在首选源上执行创建操作,然后使用原始的标准在首选源上执行另一个读取操作。这将仅返回刚添加的实体,因为最初在首选源中无法找到任何匹配标准的结果。可以将这些实体返回给客户端。对于第二种(没有 ID)子策略而言,一种可能比较有价值的做法是,允许在插入所有记录(如前所述)、或者不插入任何记录之间进行选择;这将产生使用有效 ID 添加所有内容的策略和对于无效 ID 不进行任何操作的子模式。

对于这种策略,您必须对查找操作进行标识。您不需要标识写操作,它们将简单地传递给首选源,并返回结果。通过了解备用源是否返回有效的 ID,您可以确定使用哪个子策略(第一个还是第二个)。注意:这可能是一个部署期间的问题,即源可能返回有效的 ID,但是并不支持合适的创建操作(使用这些 ID),在这个示例中,您可以为第二个子策略使用替代的方法。在迁移场景中,当与关联于备用源的某些类型的清理机制结合使用时,这个策略可能是最有价值的。这种机制(超出了这个模式范围)将周期性地运行,以删除那些不应该从备用源迁移到首选源的实体记录。例如,可以从遗留存储数据库中删除已经有六个月没有到过商店的客户的记录。当然,这样做的缺点是,如果该客户再次来到商店,在现有的数据库中将找不到他的记录。因此将该客户作为新的客户,您可能需要重新录入有关他/她的信息。

写策略

如果备用源提供了有效的 ID,或者 facade 可以为这些记录创建有效的 ID,那么 facade 可以使用这个 ID 作为键,从而记住或者缓存来自备用源的实体记录。然后,facade 将这些记录返回给客户端。如果源不能提供有效的 ID,那么 facade 简单地将这些记录返回给客户端。如果客户端调用任何用于更新来自首选源的记录(它具有有效的 ID 并且在缓存中)的操作,那么该操作可能仅提供部分信息。facade 将对 ID 进行匹配,而该 ID 必须是对缓存记录进行操作的参数中的一部分。然后它将来自客户端的信息与缓存的记录进行合并,并在首选源上调用创建操作(使用 ID),请参见图 5。

图 5:写策略
“写”策略
“写”策略

这种策略存在一些问题:

  • 要缓存这些来自备用源的记录,您需要为返回的每种值类型设置一个缓存。
  • 您必须指定某些缓存特性,比如条目的数目或者生存期,您可以从缓存模式中获得这些信息。在这个示例中,您可以考虑请求端缓存模式。
  • 从将条目放到缓存中到因为超时对其进行删除,在某些情况下,这个时间的设置可能会带来一些问题。这可能导致客户端更新已经从缓存中删除了的 ID。除了引发异常或者冒着缓存膨胀的危险将超时时间设置的足够长之外,似乎再没有什么其他的方法了。
  • 在正常的情况下,来自首选源的读取操作成功,并且您不需要使用缓存;但是,当发生更新操作时,您需要使用 ID 在缓存中进行查找,并且可能会发生缓存无法命中。如果是简单的传递操作,那么更新操作将继续下去。在这个示例中,缓存对性能产生了影响。
  • 对于这个策略,您必须在接口中标识查找和更新操作(您必须对所有的更新和创建操作应用该策略)。开发人员也必须在更新操作上提供操作特定的合并逻辑作为自定义代码。

自定义策略

以上三种策略并不能涵盖所有情况,在这种情况下,您必须使用自定义策略。您可以首先使用无操作策略以支持创建适合于您的具体情况的策略。

一些关键方面

在处理这些模式的时候,可以考虑下面的一些关键方面:

  • 通常,各种数据源都提供了所需的持久性,对于只读的情况更是如此。当允许进行写操作时,您可以使用临时缓存。
  • 访问数据源的顺序和数据源的数目,这是两个重要的性能注意事项。在大部分情况下,要使得性能实现最大化,应该使首选源成为最有可能的数据请求源。在其他情况下,比如在进行数据迁移时,将新的源(它最不可能包含所请求的数据,至少在最初的情况下)作为首选源。

相关模式

与首选数据源模式一同使用的最常用的模式是包装器模式,该模式使得不同来源的信息看起来是相同的,并且它使用了相同的 WSDL 端口类型。

在某些情况下,您可以递归地使用首选数据源模式。例如,可以使用首选数据源模式来实现商店中的服务,并且一个备用源就是企业中的一项服务。您可以使用首选数据源模式实现这个企业服务。您可以使用请求端缓存模式来实现写策略。

总结

在 SOA 环境中,可以将首选数据源模式作为企业应用程序集成 (EAI) 模式,因而典型 EAI 模式的优缺点也适用于此处。当多个源中的数据是比较一致的、清晰的和简单易懂的,并且返回的结果集比较小的时候,首选数据源模式最为合适。它提供了许多优点,包括灵活性、可扩展性、易于实现和节约成本。然而,您应该注意性能问题,因为首选数据源模式没有使用并行处理和查询优化。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=SOA and web services
ArticleID=238891
ArticleTitle=首选数据源模式的深入研究
publish-date=07052007