`
baobeituping
  • 浏览: 1068637 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

OSCache缓存技术(5)

阅读更多

第四部分:小结及其引申

 

缓存是在提升系统响应时常用的一种技术,在系统缓存上通常采用的是有页面缓存、处理缓存和数据缓存 这三种具体的类别,应该说这三种缓存在实现上还是稍有不同,尽管底层的缓存实现是一样的。

页面缓存

页面缓存是指对页面中的内容片断进行缓存的方案。比如页面中有一个部分是显示栏目中的内容的,那么就可以缓存这个部分,在进行第二次请求的时候就直接从缓存中取出这部分的内容 ( 其实就是这部分的 html 了 ) ,这种情况下,缓存的作用其实非常明显,在典型的 action+service+dao 这样的结构中,在采用页面缓存后就意味着不需要经过 action 、 service 、 dao 这些层次的处理了,而是直接就返回了,对于系统响应速度的提升来说是非常明显的。

页面缓存通常采用 oscache 来进行实现, oscache 提供了一个 jsp  tag ,可通过这个 tag 来包含需要缓存的内容部分,当然,缓存的这个内容部分需要有对服务器的请求或逻辑计算等的,可想而知,去缓存一段静态 html 是没有意义的。

其次需要定义缓存的这段内容的 key ,例如我们要去缓存页面中某个栏目的某页的内容,对于这段内容而言唯一的 key 就是栏目 ID 以及当前页数,这样就组成了这段缓存的 key 了,其实这个部分看起来好像是很简单,但有些时候会很麻烦,要仔细的想清楚这段内容的唯一的标识的 key 到底是什么, ^_^ ,通常的做法其实可以从 action 中需要获取的参数或 service 接口的参数来决定 ....

页面缓存中还需要做的一个步骤就是通知缓存需要更新,页面缓存和其他缓存稍有不同,需要告诉它,这个时候不能再使用缓存中的内容了,需要从后台再重新获取来生成新的缓存内容,这个其实很简单,因为很难在后台发生变化的时候自己来更新缓存的内容,只能是去通知它,然后让它再次发起请求来生成新的内容放入缓存中。

页面的缓存的使用对于系统的响应速度确实会有很大的提升,在实现页面缓存时最麻烦的主要是缓存的 key 的定义以及缓存更新的通知,缓存 key 的定义这个自然框架是没法解决的,不过缓存更新的通知其实在框架中可以考虑一种通知模型的, ^_^ ,就像事件通知那样 ........ 在实际的项目中,可以自己去实现一个这样的通知模型或者就是简单的采用单例方式来标识某个 key 是否需要更新。

页面缓存在实际的项目中使用非常的多。

处理缓存

处理缓存是指对于 action 、 service 、 dao 或者系统层次中的某方法进行缓存,说直接点,就是对某个类的某个方法的结果做缓存,这样在下次进行完全相同的请求的时候就可以直接取缓存了,这种响应速度的提升也是非常明显的。

处理缓存在现在的情况下其实采用任务的缓存工具包都可以实现,如 oscache 、 ehcache 、 jbosscache 等,但目前还没有处理缓存框架的出现,这个和处理缓存是否应该存在的意义也是有关系的,处理缓存框架要做到的其实就像拦截一样的方式,和 oscache  tag 类似。

同样,处理缓存的麻烦也在于怎么样去定义这个 key ,很多情况下可以根据方法的输入作为 key ,方法的输出作为 key 的值,但也会有其他一些复杂的情况,这个时候定义 key 就会变得复杂些了。

处理缓存同样有通知更新缓存的情况,和页面缓存基本是一样的。

应该说,处理缓存和页面缓存非常的相似,从实现上来说基本是完全一致的,在使用上来讲处理缓存使用的好像不多。

数据缓存

数据缓存估计大家都很熟悉,就是对系统的数据进行缓存的方式,典型的就是 Hibernate 的一级、二级数据缓存。

数据缓存在实现上如果是用 hibernate 的话更多的是直接使用 hibernate 的一级、二级以及查询缓存,如果自己要实现的话可以去参考 hibernate 的实现机制。

数据缓存的 key 在一级、二级缓存中采用的都是数据的标识键的值的方式,查询缓存采用的是查询参数、查询语句的方式。

数据缓存的更新则是 hibernate 在进行存储时直接更新缓存的内容,而对于查询缓存则是采用全部直接清除的方式,这样在下次进行查询时自然会重新去查询, ^_^ ,大家可能会想,为什么页面缓存和处理缓存不采用这样的方式来实现缓存的更新,稍微想想就知道了,在后台发生改变的时候其实是不知道需要移除哪些 key 的,所以 hibernate 为了避免这个麻烦,采用的就是当数据一旦发生改变的时候就清除全部的查询缓存,而不是只去清除相关的缓存,其实这里可以采用一种订阅式的模型,呵呵,当然,也增加了框架的复杂度。

数据缓存使用的应该是最多的,效果也是很明显的。

以上三种缓存是目前缓存实现时通常碰到的三种状况,里面按使用的多少来排序应该是:数据缓存、页面缓存和处理缓存;实现的难度上从难到易的顺序应该是:处理缓存、页面缓存、数据缓存;对于系统响应速度提升的效果来说从最好到好的顺序应该是:页面缓存、处理缓存、数据缓存。

 

 

补充部分:

       在 SSH 项目应用中,可以以对象的形式来缓存展现给用户的数据信息。对象的缓存要充分利用分组带来的好处(可以分组 删除被缓存的对象 ),这样在执行数据库的 CUD 操作时,可以调用删除相应组别的缓存对象。

示例代码:



Java代码
    private CacheManager cm;  
 
     
 
    private final static String CACHE_KEY_SUB="RetJobs";  
 
   
 
    public JobAction() {  
 
       //获取缓存管理对象  
 
       cm = CacheManager.getInstance();  
 
    }  
 
           
 
查询部分  
 
       page=(Page<RetJob>)(cm.get(CACHE_KEY_SUB+"_"+currentPage));  
 
       if(page==null){  
 
           //--------------------需要缓存对象部分-----------------------  
 
           page = retJobBaseModel.getJobs(currentPage, pageSize, statusCondition);  
 
           //-------------------------------------------  
 
           //缓存对象(含所属分组信息)  
 
           cm.put(page, CACHE_KEY_SUB+"_"+currentPage,new String[]{CACHE_KEY_SUB});  
 
       }  
 
   
 
CUD操作部分  
 
setCacheDisabled(CACHE_KEY_SUB);  
 
   
 
    private void setCacheDisabled(String group) {  
 
       //通过组别信息来删除缓存的对象。  
 
       cm.removeObjectByGroup(group);  
 
    }  
 
  

    private CacheManager cm;

  

    private final static String CACHE_KEY_SUB="RetJobs";



    public JobAction() {

       //获取缓存管理对象

       cm = CacheManager.getInstance();

    }

        

查询部分

       page=(Page<RetJob>)(cm.get(CACHE_KEY_SUB+"_"+currentPage));

       if(page==null){

           //--------------------需要缓存对象部分-----------------------

           page = retJobBaseModel.getJobs(currentPage, pageSize, statusCondition);

           //-------------------------------------------

           //缓存对象(含所属分组信息)

           cm.put(page, CACHE_KEY_SUB+"_"+currentPage,new String[]{CACHE_KEY_SUB});

       }



CUD操作部分

setCacheDisabled(CACHE_KEY_SUB);



    private void setCacheDisabled(String group) {

       //通过组别信息来删除缓存的对象。

       cm.removeObjectByGroup(group);

    }

  
CacheManager 类

Java代码
public class CacheManager {  
 
    private BaseCache newsCache;  
 
    private static CacheManager instance;  
 
    private static Object lock = new Object();  
 
   
 
    private CacheManager() {  
 
       // 这个根据配置文件来,初始BaseCache而已;  
 
       newsCache = new BaseCache("hrms", 300);  
 
    }  
 
   
 
    public static CacheManager getInstance() {  
 
       if (instance == null) {  
 
           synchronized (lock) {  
 
              if (instance == null) {  
 
                  instance = new CacheManager();  
 
              }  
 
           }  
 
       }  
 
       return instance;  
 
    }  
 
   
 
    public void put(Object news,String key,String[] groups) {  
 
       newsCache.put(key, news,groups);  
 
    }  
 
    public void remove(String key) {  
 
       newsCache.remove(key);  
 
    }  
 
    public Object get(String key) {  
 
       try {  
 
           return newsCache.get(key);  
 
       } catch (Exception e) {  
 
           return null;  
 
       }  
 
    }  
 
    public void removeAll() {  
 
       newsCache.removeAll();  
 
    }    
 
    public void removeObjectByGroup(String group){  
 
       newsCache.removeObjectByGroup(group);  
 
    }  
 


public class CacheManager {

    private BaseCache newsCache;

    private static CacheManager instance;

    private static Object lock = new Object();



    private CacheManager() {

       // 这个根据配置文件来,初始BaseCache而已;

       newsCache = new BaseCache("hrms", 300);

    }



    public static CacheManager getInstance() {

       if (instance == null) {

           synchronized (lock) {

              if (instance == null) {

                  instance = new CacheManager();

              }

           }

       }

       return instance;

    }



    public void put(Object news,String key,String[] groups) {

       newsCache.put(key, news,groups);

    }

    public void remove(String key) {

       newsCache.remove(key);

    }

    public Object get(String key) {

       try {

           return newsCache.get(key);

       } catch (Exception e) {

           return null;

       }

    }

    public void removeAll() {

       newsCache.removeAll();

    } 

    public void removeObjectByGroup(String group){

       newsCache.removeObjectByGroup(group);

    }

}

BaseCache 类增加的 2 个方法如下:



Java代码
// 添加被缓存的对象;  
 
  public void put(String key, Object value,String[] groups) {  
 
     this.putInCache(this.keyPrefix + "_" + key, value,groups);  
 
  }  
 
  //删除该组的缓存对象  
 
  public void removeObjectByGroup(String group){  
 
     this.flushGroup(group);  
 
  } 

  // 添加被缓存的对象;

    public void put(String key, Object value,String[] groups) {

       this.putInCache(this.keyPrefix + "_" + key, value,groups);

    }

    //删除该组的缓存对象

    public void removeObjectByGroup(String group){

       this.flushGroup(group);

    }

小结:
OSCache的使用主要有4种:
POJO 缓存
HTTP Response 缓存
JSP Tag Library 缓存
O/R Data Access 缓存

1)、POJO 缓存
这种方式的缓存直接调用OSCache的API进行,主要用于处理页面内容会根据参数动态改变,可以将参数设置为key值来保存数据:
首先,声明成员变量:
// OSCache Adminitrator instance
private static GeneralCacheAdministrator cacheAdmin = null;
其次,进行初始化:
public RingArtistAction() {
  cacheAdmin = new GeneralCacheAdministrator();
}
将POJO进行缓存:
  // Cache data key and refresh period
  String key = sex + ":" + place;
  int refreshPeriod = Constants.getIntegerValue(Constants.OSCACHE_REFRESH_PERIOD).intValue();
  try {
      // Get from the cache
   artists = (Map) cacheAdmin.getFromCache(key, refreshPeriod);
  } catch (NeedsRefreshException nre) {
      try {
          // Get the value (probably from the database)
    int count = getArtistCount(sex, place, errors);
    artists = getArtistData(sex, place, count, errors);
          // Store in the cache
    cacheAdmin.putInCache(key, artists);
      } catch (Exception ex) {
          // We have the current content if we want fail-over.
    artists = (Map) nre.getCacheContent();
          // It is essential that cancelUpdate is called if the
          // cached content is not rebuilt
    cacheAdmin.cancelUpdate(key);
    ex.printStackTrace();
      }
  }
 
2)、HTTP Response 缓存
这种方式的缓存用来处理整个页面的内容固定,不会根据参数动态改变:
首先在web.xml中配置CacheFilter:
<filter>
  <filter-name>CacheFilter</filter-name>
  <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
  <init-param>
   <param-name>time</param-name>
   <param-value>86400</param-value>
  </init-param>
  <init-param>
   <param-name>scope</param-name>
   <param-value>application</param-value>
  </init-param>
</filter>
将所有需要缓存的页面加入filter-mapping:
<filter-mapping>
  <filter-name>Set Character Encoding</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
注意,只有返回状态为200(HttpServletResponse.SC_OK)的内容才会被缓存

3)、JSP Tag 缓存
JSP Tag缓存主要用于缓存JSP页面的局部内容:
  <cache:cache key="especialcategory" cron="* 5 * * *">
  <jsp:include page="/ringcategory.do" flush="true" >
    <jsp:param name="ringType" value="1"/>
  </jsp:include>
  </cache:cache>

4)、O/R Data Access 缓存
请阅读参考资料的内容获取详情。



参阅资料:

[0] : http://www.opensymphony.com/oscache/

[1] : OSCache 简介

[2] : OSCache分析

[3] : OSCache——学习笔记

[4] : 应用 OSCache提升 J2EE系统运行性能

[5] : [Java]用 OSCache进行缓存对象

[6] : osCache  配置说明

[7] : 缓存漫谈

 

分享到:
评论

相关推荐

    oscache缓存技术

    **osCache缓存技术详解** osCache是一款广泛应用于Java应用程序中的开源缓存解决方案,由OpenSymphony团队开发。它提供了一种高效、可扩展的方式来管理应用程序中的数据缓存,从而提高系统的性能和响应速度。...

    oscache缓存技术应用

    **oscache缓存技术应用** **一、OSCache简介与应用** Cache技术是提升系统响应速度和性能的关键手段,尤其在Web应用中,通过缓存页面的输出结果,能够显著提高系统性能。OSCache是由OpenSymphony开发的一种创新...

    oscache缓存技术入门实例

    5. 清除缓存:当需要清除特定缓存或全部缓存时,可以调用相应方法。 ```java cacheManager.getCache("exampleCache").removeAll(); cacheManager.clearAll(); ``` 五、osCache与其他缓存方案的比较 osCache虽然...

    OSCache缓存技术(6)【实例】

    以上就是OSCache缓存技术的基本介绍,通过理解并熟练掌握OSCache,开发者能够有效地提升应用性能,降低数据库压力,为用户带来更流畅的体验。在实践中,还需要根据具体项目需求进行优化和调整,以达到最佳的缓存效果...

    OsCache缓存框架使用示例

    在压缩包中的文件,如`servlet+天气预报+缓存技术`,可能包含了一个完整的示例项目,包括了上述步骤的代码实现。你可以直接运行该项目,通过查看和分析代码来深入理解OsCache的使用方式。 总结来说,OsCache是一个...

    一个OSCache缓存技术的关键zip包

    - 在Web应用中,可以利用OSCache缓存JSP页面、EJB会话bean、Hibernate查询结果等,减少服务器负载。 - 在服务端,可以缓存经常访问的API响应,提升响应速度,改善用户体验。 - 结合Spring框架,可以通过AOP(面向...

    基于OSCache的页面缓存(收藏)

    **基于OSCache的页面缓存技术详解** 在Web应用程序中,页面缓存是一种常见的优化策略,它可以显著提高网站性能,减少服务器压力,并提供更快的用户体验。OSCache是Apache软件基金会的开源项目,它是一个高性能、...

    OSCache缓存技术

    Cache是一种用于提高系统响应速度、改善系统运行性能的技术。尤其是在Web应用中,通过缓存页面的输出...OSCache是个一个被广泛采用的高性能的J2EE缓存框架,OSCache还能应用于任何Java应用程序的普通的缓存解决方案。

    OSCache 缓存对象的总结

    5. **缓存分区**:OSCache 支持将缓存划分为多个分区,每个分区可以有不同的配置,这有助于管理和优化大量数据的存储。 6. **缓存预热**:在应用启动时,OSCache 可以预先加载一部分关键数据到缓存中,以缩短用户...

    OSCache缓存jsp例子

    缓存是一种存储技术,用于临时存储频繁访问的数据,以便快速检索。在Web开发中,JSP页面缓存可以减少服务器对数据库的查询次数,从而减少服务器负载和提高用户访问速度。 OSCache 提供了对Java对象的缓存管理功能,...

    缓存技术 oscache-2.3.2.jar包下载

    缓存技术 oscache-2.3.2.jar包下载

    oscache-java缓存框架

    - **缓存**:缓存是一种技术,用于临时存储频繁访问的数据,以便快速响应用户的请求,减少系统处理时间和资源消耗。 - **Java缓存框架**:在Java环境中,缓存框架如osCache提供了一套完整的解决方案,帮助开发者...

    oscache对象缓存

    在IT领域中,缓存技术是提高系统性能的关键一环,尤其是在高并发、大数据量的应用场景下。oscache,全称OpenSymphony OSCache,是一个广泛使用的开源Java对象缓存框架,它允许开发者将数据存储在内存中,以减少对...

    oscache-JSP缓存

    **osCache - JSP缓存技术详解** osCache是由OpenSymphony开源组织开发的一个高效、易用的缓存解决方案,特别适用于Java Web应用程序,尤其是JSP页面。它为开发者提供了一种在JSP页面内部实现快速内存缓存的机制,...

    hibernate+oscache实现二级缓存实例

    为了提高系统性能,通常会采用缓存技术来减少对数据库的直接访问,而OSCache就是一种广泛使用的开源缓存解决方案。本实例将介绍如何结合Hibernate和OSCache实现二级缓存,以优化应用程序的性能。 一级缓存是...

    SSM的整合+OScache页面缓存+freemark模板

    配置OScache主要包括设置缓存策略、缓存范围以及缓存失效策略等。 【Freemarker模板】 Freemarker是一个基于模板的Java模板引擎,用于生成动态内容。它与SpringMVC配合使用,可以方便地生成HTML页面。开发者编写...

    OSCache学习例子 实例

    5. **从OSCache获取缓存数据**:在需要的地方,可以通过键来检索缓存的对象。 ```java Cache cache = CacheManager.getInstance().getCache("myCache"); Object object = cache.get("key").getValue(); ``` 6. ...

    oscache的使用实例和详解

    - **缓存**: 缓存是一种存储技术,用于暂时存储常用数据,以便快速访问。在osCache中,缓存以“区域”(Cache Regions)的形式组织,每个区域可以存储一组相关的数据。 - **缓存项**: 存储在缓存中的单个数据单元...

    Oscache框架的搭建步骤

    在现代Web开发中,缓存技术是提升系统响应速度、优化用户体验的关键策略之一。Oscache框架作为一种高效、灵活的缓存解决方案,在Java Web应用,尤其是JSP环境中,提供了强大的缓存管理功能。本文将深入探讨Oscache...

    基于OSCache的页面缓存

    【基于OSCache的页面缓存】是Web应用中一种有效的性能优化策略,它涉及到缓存技术、分布式系统以及系统开发等多个领域。OSCache是开源的Java缓存框架,能够帮助开发者实现高效的页面和数据缓存,从而降低数据库的...

Global site tag (gtag.js) - Google Analytics