2010-05-10 75 views
1

我有一个需要8分钟渲染的JSP。代码逻辑本身不能更有效率(它会经常更新并且基本上被一个尖尖的老板所更新)。我试图用缓存层包装它,如用JSP构建异步缓存模式

<%@ taglib uri="/WEB-INF/classes/oscache.tld" prefix="oscache" %> 
<oscache:cache time="60"> 
    <div class="pagecontent"> 
    ..... my logic 
    </div> 
</oscache:cache> 

这很好,直到60秒结束。之后的下一个查询会阻塞,直至再次完成8分钟的渲染。我需要一种方法来建立一个模式是这样的:

  1. 如果没有版本在缓存中运行的实际逻辑的动态内容(和填充后续请求的高速缓存)
  2. 如果有高速缓存中的动态内容的非过期版本服务于来自高速缓存的JSP逻辑的输出
  3. 如果在高速缓存中存在动态内容的过期版本,则从高速缓存服务JSP逻辑仍然的输出AND在后台运行JSP逻辑,以便缓存以透明方式更新到用户 - avoi用户必须等待8分钟

我发现至少EHCache可能能够做一些异步缓存更新,但它并不可悲地似乎适用于JSP标签......另外我必须为JSP的实际逻辑取10-20个参数,其中一些应该用作缓存的关键字。

代码示例和/或指针将大大地赞赏。如果提供的解决方案非常难看,我不坦率地关心。我只想要一个简单的5分钟缓存异步缓存更新考虑到一些参数作为关键。

回答

2

如果您的缓存数据在所有用户中都是通用的,那么使用JSTL application作用域可以缓存您的JSP片段。如果是每个用户,那么范围为session

除此之外,使用另一个变量记录缓存刷新时间戳,或者相反地记录到期时间。下面的例子:

<c:if test="${empty cachedData}"> 
<c:set var="cachedData" scope="application"> 
<%-- Cached JSP content goes here --> 
</c:set> 
<c:set var="cachedRefreshTimestamp" 
    value="<%= new Long(new java.util.Date().getTime()) %>" 
    scope="application"/> 
</c:if> 

随后:

如果(系统当前时间+ 5)> cachedRefreshTimestamp,去在分开的循环再次获取数据,改写回cachedData,并更新cachedRefreshTimestamp也