庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

资源获取模式

Posted on 2008-09-07 22:10 dennis 阅读(2343) 评论(1)  编辑  收藏 所属分类: 模式与架构java
    任何应用都需要与资源打交道,这个资源可能是文件、内存、网络、数据库、web服务等。特别是系统的可伸缩性和性能上,一个系统的可伸缩性很大程度上取决于该系统资源管理的可伸缩性。资源的获取是资源生命周期的起点,因此在此阶段的优化和配置对系统性能、可用性、稳定性、可伸缩性的影响是至关重要的。资源的获取要解决 这么两个问题:怎么找到资源,何时获取资源。
    资源的超找可以通过lookup模式,所谓lookup模式就是引入一个查找服务作为中介,让资源使用者可以 找到并使用资源提供者提供的资源。这方面一个显然的例子就是JNDI,我们通过JNDI查找EJB、数据库连接池等,另一个例子就是RMI,客户端通过命名服务查找到远程对象。查找服务提供查询语言,也提供接口让服务注册到它的容器内。
    何时获取资源?根据时机的不同可以分为预先获取模式和延迟获取模式。如果对系统的可用性和运行时性能要求比较高,那么可能你会预先加载或者分配所要用到的资源,通过一个资源提供者的代理对象拦截对资源的请求,返回预先加载或者分配的资源,从而提高系统性能。这方面的例子就是 memcached,memcached启动时预先分配内存来提高性能(相应的带来的是内存的不能有效利用)。线程池、数据库连接池也是预先获取模式的例子,通过预先创建的线程或者数据库连接,来提高系统的整体性能。反之,延迟获取模式就是尽可能到使用资源的最后一刻才去获取资源,一开始返回的只是一个资源的代理对象,真正使用到资源的时候由这个代理对象去加载实际的资源。延迟获取模式的例子也很多,例如 Hibernate的延迟加载,延迟加载的对象其实是一个代理类(通过java动态代理或者cglib增强),只有真正用到的时候才去数据库获取实际的数 据。函数式编程中的延时求值也是延迟获取模式的例子,没有求值前只是个promise,求值到的时候才force执行。Singleton模式下的单例也常常做延迟初始化,这是延迟获取模式的特化。
    如果资源的大小很大、极大或者是未知尺寸,预先获取会导致系统速度的缓慢甚至耗尽系统资源,延迟获取在获取的时候也可能时间过长难以忍受或者耗尽系统资源,两者都不适合,解决办法就是分步获取,这就是所谓部分获取模式。将资源的获取分为两步或者多步,每一步获取一定数目的资源,每一步获取资源也可以采用预先或者延迟的策略。这样的例子如socket读数据到缓冲区,一次可能只读一部分数据到缓冲区,分步才读完。再比如web页面一棵树的展 现,一开始可能只是显示部分节点,在需要查看一些节点的时候才会通过ajax加载和展开它们的子结点乃至深层子结点。

参考:POSA3 第二章

评论

# re: 资源获取模式  回复  更多评论   

2008-09-08 09:34 by Jack.Wang
说的很好,其实微观点每个对象都是一个资源,资源的获取在设计上应该尽量在一个进程中,跨进程就会有网络开销(即使在同一台机子),比如分布式的 CORBA,RMI,EJB,就会影响性能,所以在性能要求高的应用中尽量本地获取资源,即单进程,大家可以看看 ebay, myspace 等等的大型网站的架构。

只有注册用户登录后才能发表评论。


网站导航: