池的概念
本词条缺少概述图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
池,即Pool(池),网络技术名称,应用在服务器端软件的开发上。
- 中文名
- 池
- 概 念
- 在服务器端软件的开发上
- 资源池
- 资源放置于内存对象中以备使用
- 分 析
- 中出现的所有实体
池的描述和定义:Pool(池)的概念被广泛的应用在服务器端软件的开发上。使用池结构可以明显的提高你的应用程序的速度,改善效率和降低系统资源的开销。所以在现在的应用服务器端的开发中池的设计和实现是开发工作中的重要一环。那么到底什么是池呢?我们可以简单的想象一下应用运行时的环境,当大量的客户并发的访问应用服务器时我们如何提供服务呢?我们可以为每一个客户提供一个新的服务对象进行服务这种方法看起来简单,在实际应用中如果采用这种实现会有很多问题,显而易见的是不断的创建和销毁新服务对象必将给造成系统资源的巨大开销,导致系统的性能下降。针对这个问题我们采用池的方式。池可以想象成就是一个容器保存着各种我们需要的对象。我们对这些对象进行复用,从而提高系统性能。从结构上看,它应该具有容器对象和具体的元素对象。从使用方法上看,我们可以直接取得池中的元素来用,也可以把我们要做的任务交给它处理。所以从目的上看池应该有两种类型,一种是用于处理客户提交的任务的,我们通常用Thread Pool(线程池)来描述它,另一种是客户从池中获取有关的对象进行使用,我们通常用 Resource Pool(资源池)来描述它。它们可以分别解决不同的问题。以下结合具体的应用进行介绍。
首先介绍资源池(有时也可以叫做对象池)资源池可以维护多种可以重用的资源。资源池最基本的思想就是预先建立一些资源放置于内存对象中以备使用,例如Socket连接,JDBC连接,CORBA 对象 tuxedo连接等等。举一个简单的WEB数据查询的例子,用户通过服务器建立一个JDBC连接,然后查询,最后关闭。如果用户量比较大那么对JDBC的连接管理就自然会成为应用瓶颈。
采用资源池可以用来在多个客户访问时提供对共享资源的管理机制。当一个客户访问一种指定类型的资源时,服务器不是简单的分配给客户新的资源而是从池中取得已经实例化的资源对象为它服务。
分析:
首先我们分析一下这个问题中出现的所有实体,通过分析他们的共性来设计统一的接口。
我们可以得到一个ConnManger对象,通过它提供对多个Pool对象的创建和管理和为客户提供对资源的存取方法。一个采用特定的数据结构实现的Pool 对象用于存取指定类型的资源对象。对各种资源对象的抽象描述接口IpoolItem。所有需要重用的资源对象都要实现这个接口。
通过这三个基本的类和他们的方法,就可以实现一个简单的资源池。下面我们进一步对它们进行改动,增加一些更有效的管理方法。
改进:
错误恢复:在资源池中最常见的问题时如何处理出现异常的资源对象。池的实现必须提供完整的机制进行资源的保护,资源对象为什么会出现异常呢,让我们分析一下一个多客户的服务器程序可能出现的问题。一个资源在长时间使用后,连接可能发生了超时;数据服务的进程可能发生了退出;网络可能中断等等。那么这个资源对象的状态就会相应的中断,使用这个资源的客户端就会发生异常,而且我们要求客户端在使用完资源后把这个资源放回池中,所以这一定会影响其他客户对资源的访问,进一步使情况恶化,如果不对这种状况进行处理,很有可能池中的所有资源都会变成不可用,从而服务器无法提供服务。我们必须提供一种方式使池可以处理发生故障的资源对象。而不是简单的把对象放回池中。所以我们对ConnManager和Pool对象提供新的方法repairConnection()和fixConnection();使客户端在发现资源异常时可以使用这个方法通知池恢复出错的资源对象。动态管理:在系统的运行时客户的请求数量往往是一种具有波峰和波谷的曲线,所以我们希望在系统允许的范围内,提供对池的动态管理简单的说就是在峰值请求时池会动态的调整加大池的尺寸提供更多的可供使用的资源;波谷时减小池的尺寸进行资源的回收。考虑到这个目的,所以为Pool对象增加一个后台运行的监视线程在池对象创建后,按照一定的算法进行检测Pool对象的运行状态,实现动态调整的功能。补充说明一点如果Pool对象的内部数据结构的不同,可以提供更为丰富的管理机制。统一的接口。ConnManger对池对象的创建采用从配置文件中读取配置信息的方式,动态的加载特定的PoolItem实例到相应的Pool对象中。从而可以保证池的多元性。
前面已经提到了很多的应用服务器,都需要处理从客户端发起的任务请求,这些任务往往具有高密度,短时间的特性,无论通过什么方式在服务器得到client 请求后,服务器就需要独立的处理这个客户请求。针对这个的问题,线程池提供了处理系统性能和大用户量请求之间的矛盾的方法,通过对多个任务重用已经存在的线程对象,降低了对线程对象创建和销毁的开销,由于当客户请求到了时,线程对象已经存在,可以提高请求的响应时间从而整体的提高了系统服务的表现。
下面给出一个线程池的简单设计样例(参见图2)
分析:
在这个环境中,我们必须注意到一个问题就是线程的逻辑和应用的任务逻辑的分离,不能把用户的应用逻辑固化到线程池的实现中。如果没有达到这个目标那么这个线程池的实现是有一定的局限性的。为了实现这一点,必须对线程池的运行逻辑进行抽象通过一个任务的抽象接口来模拟客户提交的任务。
一个ThreadPool对象,它管理和创建可重用的线程对象TaskRunable,通过runTask方法接受客户提交的任务,并选择可以使用的线程对象调用它的getTaks方法使其执行任务。线程池中重用的线程对象 TaskRunnable。它是一个独立的线程对象,通过getTask方法执行由所在容器ThreadPool传递的任务。任务对象接口Itask。所以的客户任务都必须实现这个接口,从而保证线程逻辑和应用逻辑的分离。
改进: