资源获得
2.1 Lookup模式
Lookup(查找)模式描述了如何通过使用查找服务作为中介实例来发现和访问资源(不管资源是本地的还是分布的)。
1.问题
资源提供者可能提供了一个或多个资源给资源使用者。随着时间的流逝额外的资源可能会增加出来,或者存在的资源可能被资源提供者移走。资源管理者发布存在资源的可获取性的一种方式是以一定的时间间隔向感兴趣的资源使用者发布广播消息。这样的消息必须每隔一段时间就发布一次,以确保加入系统的新的资源使用者知道可用的资源。相反,资源使用者也可以发送广播消息请求所有可用的资源提供者响应。一旦资源使用者从所有可用资源提供者处获得了回复,它就可以选择其所需要的资源。但是,两种方式可能都相当低效,并且代价高昂,因为它们产生了大量的消息,若是分布式系统的话,这些消息会充满整个网络。为了解决问题,让资源提供者发布资源,并且让资源使用者以开销较小的方式有效地找到这些资源,需要解决如下问题:
·可用性(Availability)。资源使用者应当可以根据需要找到在其环境中哪些资源可用。
·自举性(Bootstrapping)。资源使用者应该可以获取资源提供者的初始引用。
·位置独立性(Location independence)。资源使用者应当可以从资源提供者获取资源,无论资源提供者位于何处。类似地,资源提供者应该可以为资源使用者提供资源,而不必知道资源使用者位于何方。
·简单性(Simplicity)。当查找资源时,解决方案不应当给资源使用者带来负担。类似地,解决方案也不应当为资源提供者带来负担。
2.解决方案
提供资源查找服务,使得资源可被资源使用者获得。资源提供者通过查找服务来发布资源,并附着描述其发布的资源的属性。这样资源使用者就可以先通过属性来查找被发布的资源,然后获取资源再使用资源。
对于需要在使用前获取的资源,资源提供者把指向它们自己的引用同描述其提供的资源的属性一起注册,这样资源使用者就可以获得这些被注册的引用,并使用它们来从被引用的资源提供者获取可用资源。
对于不需要在使用前获取而可以直接访问的资源,比如可同步重用的服务,资源提供者把指向资源的引用同描述资源的属性一起注册。这样资源使用者就可以直接访问资源,而不必先同资源提供者打交道。
查找服务成为了资源使用者和资源提供者之间的通信中点。它使得资源使用者在明确需要以资源提供者获取资源时可以访问资源提供者。此外,查找服务也使得资源使用者可以直接访问不需要从资源提供者获取的资源。在这两种情况下,资源使用者都不需要资源提供者的位置。类似地,资源提供者也不需要知道想要获取并访问它们提供的资源的资源使用者的位置。
3.结构
资源使用者(Resource User)使用资源。
资源(Resource)是一个实体,比如一个提供某种类型的功能的服务。
资源提供者(Resource Provider)提供资源,并通过查找服务分布资源。
查找服务(Lookup Service)提供了让资源提供者通过到其自身的引用发布资源,并让资源使用者找到这些引用的能力。
4.实现
1)决定查找服务的接口。查找服务应当为资源的分布和查找提供方便,或者直接实现,或者通过它们的资源提供者来实现,它应当提供一个接口,让资源提供者可以注册以及注销引用。
可以为查找服务定义不同的策略。例如,查找服务可以支持与重复的名称或者属性的绑定。查找服务应当提供一个接口,让资源使用者可以获取所有可用资源提供者的列表。
2)决定是注册资源引用还是资源提供者的引用。如果资源必须先由资源使用者显式获取,那么就应当向查找服务注册提供那个资源的资源提供者的引用,并且一起注册描述资源提供者所提供的资源的属性。要求显式获取资源有利于控制可以访问资源的资源使用者的类型。
当资源提供者提供多个资源时,资源提供者的引用可以用于辨识资源。这有助于允许资源提供者把获取请求同需要的资源相关联。
另一方面,如果资源不需要被显式获取,而是可以被资源使用者直接访问,那么就可以向查找服务注册资源的引用,并且一起注册描述资源的属性。例如,对于可以同时被重用的资源,可以通过向查找服务注册资源引用的方式来使得资源使用者可以直接使用资源。这类资源的例子包括只读对象和Web Service。这样的资源或者没有同步问题,或者自身可以对访问同步。
3)实现查找服务。在内部,查找服务可以用很多种方式实现。比如,查找服务可以用某种树型数据结构来保存注册的引用以及它们的元数据,这在必须为复杂的依赖关系建模时很有帮助,或者也可以用简单的哈希表来保存。对于非关键并且经常改变的资源发布,信息可以临时性地存储;而对于关键的发布,则应该把关联以某种恰当的后端持久化机制来持久存储。
4)提供查找服务访问点。为了同查找服务通信,访问点是必需的。访问点可以是一个Java引用,一个C++指针或引用,也可以是一个通常会包含查找服务所有的主机名、端口号的分布式对象引用等等。这一信息可以以几种方式分布给资源提供者和资源使用者,比如写到一个资源提供者和资源使用者可以访问的文件,或者通过定义好的环境变量。
如果查找服务没有发布访问点,那么就需要设计一个自举协议来使得资源提供者和资源使用者可以获得访问点。这样的自举协议通常会用广播或者多播协议来设计。资源提供者或者资源使用者用自举协议发送一个要求查找服务的引用的初始请求,收到请求之后,通常一个或者多个查找服务会向请求者发送回应,把它们的访问点传递过去。然后资源提供者就可以同查找服务联系以发布自己的引用。类似地,资源使用者可以同查找服务联系以获得注册的资源提供者的引用。
5)决定查询语言。查询服务可以选择支持一种查询语言,使用资源使用者可以用复杂的查询来寻找资源。
5.结论
优点:
1)可获得性(Availability)。使用查找服务,资源使用者可以根据需要找到在它的环境中哪些资源可用。请注意,资源或者其相应的资源提供者可能会变得不再可获得,但它的引用可能尚未被从查找服务中删去。
2)自举(Boostrapping)。查找服务使得资源使用者可以获得初始的资源。在分布式系统中,自举协议使得资源使用者可以找到查找服务并用它来找到其他的分布式服务。
3)位置独立性(Location independence)。查找服务提供了位置透明性,这是因为它向资源使用者屏蔽了资源提供者的位置。类似地,该模式也向资源提供者屏蔽了资源使用者的位置。
4)配置简单性(Configuration simplicity)。基于查找服务的分布式系统需要很少或者不需要手工配置。不需要为了分发、发现或者访问远程对象而共享或者传输文件。自举协议的使用是自组网络场景(在这样的场景中环境经常改变并且无从预知)的关键特性。
5)基于属性的选择(Property-based selection)。资源可以基于属性来选择。这样就使得细粒度地匹配用户需求和资源分布成为可能。
缺点:
1)单一失败点(Single point of failure)。Lookup模式带来的一个后果是,如果查找服务的一个实例崩溃了,那么系统可能会失去注册的引用及其相关属性。等查找服务重启之后,资源提供者需要重新向其注册资源,除非查找服务具有持久化的状态。这可能既令人厌烦又容易导致错误,因为它要求资源提供者来检测查找服务是否崩溃并且重启。此外,查找服务还可能会成为瓶颈,影响系统的性能,所以更好的解决方案是对查找服务引入复制。
2)悬挂引用(Dangling referneces)。Lookup模式带来的另一个后果是产生悬挂引用的危险性。随着相应的资源提供者终止服务或者被移走,注册到查找服务的引用可能会变得过时。在这种情况下,Leasing模式可以提供帮助,它强迫资源提供者定期地“续借”它们的引用(如果它们不希望自己的引用被自动删除的话)。
3)不想要的复制(Unwanted replication)。当具有相同属性的类似资源进行发布,但又不想进行复制时,就会产生问题。取决于查找服务的实现,相同资源的多个实例可能会错误地注册,或者一个资源提供者可能会覆写前面一个资源提供者的注册。确保至少一个属性是唯一的可以避免这个问题。