3.4 Resource Lifecycle Manager模式
Resource Lifecycle Manager(资源生命周期管理器)模式引入了一个单独的Resource Lifecycle Manager,从而把资源的生命周期管理同它们的使用解耦合了。
1.问题
建立大规模的系统很有挑战性。使大规模系统健壮并且具有伸缩性更具挑战性。使大规模系统健壮并且具有可伸缩性的最重要因素是如何管理资源。系统中的资源可能具有很多种不同的类型,比如网络连接、线程、同步原语、服务等。网络连接代表了客户应用程序和分布式应用服务之间的通信渠道。高效地管理它们需要有能力判断何时建立连接,何时释放连接。线程对大规模系统特别重要,因为它们提供了应用程序不同部分之间的异步行为,例如可以把UI交互和典型的客户端功能以及服务提供解耦合。但是,高效地管理线程会很有挑战性,因为这涉及紧密监测它们的执行,并且判断何时创建新线程,何时释放不需要的线程的能力。类似地,我们通常需要锁和令牌之类的同步原语来对应用程序的异步部分进行同步,并且使得它们的内部协调和交互成为可能。但是何时以及如何创建这些同步原语很重要,而且实现起来也很有准度。
1)可用性(Availability)。可用资源的数目通常和系统的整体尺寸不会同步增长。因此,在大系统中,有效且高效地管理资源很重要,这样才能确保在用户需要时有资源可用。
2)可伸缩性(Scalability)。随着系统变得更大,需要管理的资源数目也会增加,使得用户更难直接管理。
3)复杂性(Complexity)。大系统通常在资源之间会有复杂的相互依赖关系,很难跟踪这些关系。为了让资源可以在不再需要的时候正确而及时地释放掉,维护和跟踪这些相互依赖关系是很重要的。
4)性能(Performance)。通常很多优化的目的都是确保系统不会遇到任何性能瓶颈。但是,如果由单个资源使用者来进行这样的优化,可能会相当复杂。
5)稳定性(Stability)。如果资源使用者不得不管理资源生命周期的事项,它们可能会忘记释放资源,久而久之就会导致系统稳定性的问题。此外,还应该可以控制资源的获取,以确保在系统层次上可用资源不会发生“饥荒”,从而避免不稳定性。
6)相互依赖性(Interdependencies)。在复杂的系统中,相同或者不同类型的资源可能会相互依赖,这意味着资源的生命周期也会是相互依赖的,需要正确地管理。
7)灵活性(Flexibility)。对资源生命周期的管理应该是灵活的,可以支持不同的策略。策略应该提供钩子,从而允许配置资源管理行为。
8)透明性(Transparency)。资源生命周期的管理对资源使用者应该是透明的。特别是,资源使用者应该不需要被迫与资源管理的复杂性打交道。
2.解决方案
把资源的使用同资源管理相分离。引入单独的Resource Lifecycle Manager(RLM),它的唯一职责就是管理和维护资源使用者用到的资源。
资源使用者可以用RLM来获取和访问特定的资源。如果被资源使用者请求的资源尚不存在,RLM会执行资源的创建工作。此外,RLM还允许用户请求显式地创建资源。
RLM知道当前的资源使用情况,所以可以拒绝来自资源使用者的资源获取请求。例如,当系统可用内存已经很少了,那么RLM可以拒绝资源使用者的分配内存请求。
RLM还控制它管理的资源的回收,或者对于使用者透明,或者响应使用者的显式请求。RLM基于考虑到可用计算资源(比如内存、连接和文件句柄)的合适的策略来维护资源。
RLM可以负责一类资源,也可以负责多种类型的资源。如果资源之间存在相互依赖关系,那么针对每一类资源的RLM会协同工作,这意味着它们需要维护资源间的依赖关系。这可以由一个中心RLM对其余各个RLM以及相互依赖的资源负责,也可以让一个单独的RLM只处理相互依赖关系,而把对相同类型的资源的管理留给各类资源的RLM。在层次分明的构架中,可以使用层级RLM,这样的RLM在每个抽象层次(比如OS、框架、应用程序层)都存在。
3.结构
资源使用者获取和使用资源。
资源是一个实体(比如网络连接或者线程)。
资源生命周期管理器(RLM)管理资源的生命周期,包括它们的创建/获取、重用和析构。
资源提供者(比如操作系统)拥有并管理资源。资源提供者本身也可以是一个在相同或者不同抽象层次上的资源生命周期管理器。
4.实现
1)判定需要管理的资源。开发者首先需要识别出需要管理生命周期的所有资源。因为资源的类型多种多样,所以应用程序可以为不同类型的资源提供多个RLM,例如一个RLM用于处理进程、线程、文件句柄和连接之类的计算资源,另一个RLM用于维护应用程序组件。不过,也可以用一个RLM来处理不同类型的资源。当需要在不同类型的资源之间维护复杂的相互依赖关系时,这样的解决方案可能比较有效,如果只需要一个RLM实例,它应该被实现为Singleton。
2)定义资源创建和获取语义。开发者需要决定RLM如何创建或者获取资源。
这既包括决定资源何时创建或者获取,也包括资源如何创建或者获取。Eager Acquisition、Lazy Acquistion、Partial Acquisition之类的模式可以用来控制何时获取资源,而Factory Method模式和Abstract Factory模式则可以控制资源如何创建。请注意,通常资源由RLM来获取,所以RLM可以对这些资源的生命周期有完全的控制。但是,也可能存在这样的情况:一些资源不是由RLM获取或者创建的,但还是需要由RLM来管理。
为了确保系统的稳定性,RLM可以以多种理由(包括资源不够用的情况)拒绝资源使用者的资源获取请求。
3)定义资源管理语义。RLM的一个主要职责是有效且高效地管理资源。频繁的资源获取和释放可能代价高昂,所以RLM通常会使用Caching和Pooling这样的模式来优化对资源的管理。
4)处理资源的依赖关系。为了管理资源的依赖关系,可以考虑使用一个具有公共职责的RLM。这样的RLM的确切可行性,以及它的实现,与应用程序背景和资源类型密切相关。一个可能的解决方案是把相互依赖的资源划入一个组。这样的分组可以用于控制相互依赖的资源的获取,访问和释放。
5)定义资源释放语义。当资源不再被需要时,它们应当自动被RLM释放。Leasing和Evictor这样的模式可以用来控制何时以及如何释放资源。
6)定义资源访问语义。被创建或获取的资源应该易于访问。RLM可以使用Lookup之类的模式来简单地访问资源。
7)配置策略。对于前面的每一步,RLM都应该允许配置不同的策略来控制如何管理资源的生命周期。
5.结论
优点:
1)效率(Efficiency)。单个使用者来管理资源的效率比较低。Resource Lifecycle Manager模式允许对资源进行协调和集中式的生命周期管理,这使得进一步的应用程序优化成为可能,并且降低了总体的复杂性。
2)可伸缩性(Scalability)。使用Resource Liftcycle Manager模式允许更有效的资源管理,使得应用程序可以更好地利用可用的资源,这使得应用程序可以承受更高的负荷。
3)性能(Performance)。Resource Lifecycle Manager模式可以确保多个层次的优化成为可能,从而从系统获得最佳的性能。通过分析资源的使用情况和可用性,可以用不同的策略来优化系统性能。
4)透明性(Transparency)。Resource Lifecycle Manager模式使得资源管理对于用户透明,可以配置不同的策略来控制资源的创建和获取、管理以及释放。通过把资源使用和资源管理解耦合,RLM降低了使用复杂性,从而让资源使用者变得轻松。
5)稳定性(Stability)。Resource Lifecycle Manager模式可以确保只有有足够数目的资源的情况下才会把资源分配给用户,这避免了在资源使用者可以直接从系统获取资源的情况下容易导致的资源“饥荒”,从而有助于提升系统的稳定性。
6)控制(Control)。Resource Lifecycle Manager模式允许更好地控制对相互依赖的资源的管理。通过维护和跟踪资源间的依赖关系,RLM可以正确并且及时地在资源不再被需要时释放它们。
缺点:
1)单点失败(Single point of failure)。RLM中的bug或者错误会导致应用程序的很多部分失败。冗余概念只能起到部分作用,因为复杂性进一步增加,性能则受到进一步的限制。
2)灵活性(Flexibility)。当单个资源实例需要特殊对待时,Resource Lifecycle Manager模式可能灵活性很不够。