论坛首页 Java企业应用论坛

Roller如何缓存页面

浏览 2142 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-10-12  

前面的文章已经谈了roller是如何生成页面的,其实页面就是一些HTML代码。在roller中,使用一个类CachedContent对象来包装这些HTML代码,然后才把CachedContent对象放到缓存中以便以后使用。

 

谈到缓存,roller的开发者们绝不会放过任何一个提高性能的机会。首先利用浏览器的缓存功能,见如下代码:

            if (ModDateHeaderUtil.respondIfNotModified(request, response, lastModified)) {
                return;
            } else {
                // set last-modified date
                ModDateHeaderUtil.setLastModifiedHeader(response, lastModified);
            }

 

 

接下来谈谈roller如何为了提高性能如何利用内存来实现缓存的。这里说的主要针对博客页面的缓存处理。为了叙述方便,下面的是笔者根据源代码整理的类图:

 

 

在图中,有两个单例类,分别是CacheManagerWeblogPageCache。其中WeblogPageCache有一个Cache属性,在实例化时通过CacheManager实例获取一个Cache对象。

 

CacheManager实例化时要通过读取属性文件来初始化cacheFactory属性,默认情况下cacheFactory是一个ExpiringLRUCacheFactoryImpl对象。这里应用了工厂模式。

 

通过图中我们可以知道WeblogPageCachecontentCache属性实际是一个ExpiringLRUCacheImpl对象。

 

我们知道缓存很好用,put进去get出来。看起来简单,但真正的缓存系统要做很多工作,比如是否过期了,如何清理缓存等等。

 

Roller中定义了一个Cache接口,代表一个缓存。有两个实现类,分别是LRUCacheImplExpiringLRUCacheImpl,他们是父子关系。实现了LRU算法的缓存策略。作为缓存接口自然少不了这几个重要的方法:putgetremoveclear

 

WeblogPageCache类为我们屏蔽了很多实现细节,如果是作为缓存的使用者,只要了解WeblogPageCacheAPI就可以了。WeblogPageCache同样也有和Cache类似的方法,这些对应的方法其实是把请求委派给Cache来处理。WeblogPageCache还有一个重要的方法generateKey,生产key很重要,但笔者不打算在这里讲。

 

通过类图和前面的文字介绍,我们可以知道系统是如何准备好缓存等待我们使用的了。

 

前面提到html被包装到CachedContent对象中,当页面需要缓存时,WeblogPageCacheput方法被调用,传入一个keyCachedContent对象。同时new一个LazyExpiringCacheEntry对象来包装CachedContent。为什么这样做呢?目的是为了在get时判断数据是否有效。

 

先说说本人对缓存的两个概念(有效和过期)的理解。有效是指被缓存的数据已经被修改过了;过期是指当被缓存的数据超过了缓存系统设定的时间长度。

 

WeblogPageCacheput时,其实是把请求委派给Cache对象的,而这个Cache就是一个ExpiringLRUCacheImpl对象。ExpiringLRUCacheImplput方法被调用时,又new了一个ExpiringCacheEntry对象来包装LazyExpiringCacheEntry对象。这样做的目的是为了在get时判断被缓存数据是否过期。

 

缓存的put过程就是这样的,下面说说如何从缓存中取出数据,取出数据是通过调用get方法。

 

 

当想获取一个缓存数据时需要调用WeblogPageCacheget方法,此方法需要传入一个key和一个博客最近修改时间。Get的过程不是很好描述。WeblogPageCache把请求传给Cache对象上的get方法。在Cacheget方法中通过keyMap中取出value,这个value先是一个ExpiringCacheEntry对象,因为此对象被new时初始化了超时时间和缓存时间。所以通过

    public boolean hasExpired() {
        
        long now = System.currentTimeMillis();
        
        return ((this.timeCached + this.timeout) < now);
    }

 

可以判断一个数据是否过期。如果过期就被从缓存中删除了,否则就从ExpiringCacheEntry中取出value(也就是LazyExpiringCacheEntry)返回。

 

一个数据不过期并不代表能使用,还要判断他是否有效。程序控制权回到WeblogPageCacheget方法。如果Cacheget方法不是null,就要判断是否有效。LazyExpiringCacheEntry对象被new出来时,它的被缓存时间也同时被初始化。由于它是包装CachedContent对象的,因此它也有个get方法,参数是最近修改时间。在此方法中,通过判断最近时间是否大于缓存时间来确定数据是否有效。

 

如果数据是有效的就把CachedContent返回,否则就返回null。整个缓存的get过程就这样结束了。

 

体会:roller的缓存用了工厂模式,这样的好处是:当我们的站点规模变大时,roller缓存可能满足不了要求,这时如果使用优秀的缓存系统(比如memcached)是比较容易集成到roller中的。

 

欢迎大家一起讨论roller。。。。。。 

 

   发表时间:2010-10-19  
搂主,请继续!
0 请登录后投票
   发表时间:2010-12-20  
楼主强大,类图都画出来了,鼓励,支持。但是我想问问,那个编辑器如何弄进去,我本地没有编辑器。
0 请登录后投票
   发表时间:2010-12-20  
什么编辑器啊,画图的吗,我是用rose画的,导出图片上传到je,再插入图片
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics