java eeWEB缓存技术.docx

上传人:b****5 文档编号:12148535 上传时间:2023-04-17 格式:DOCX 页数:62 大小:157.09KB
下载 相关 举报
java eeWEB缓存技术.docx_第1页
第1页 / 共62页
java eeWEB缓存技术.docx_第2页
第2页 / 共62页
java eeWEB缓存技术.docx_第3页
第3页 / 共62页
java eeWEB缓存技术.docx_第4页
第4页 / 共62页
java eeWEB缓存技术.docx_第5页
第5页 / 共62页
点击查看更多>>
下载资源
资源描述

java eeWEB缓存技术.docx

《java eeWEB缓存技术.docx》由会员分享,可在线阅读,更多相关《java eeWEB缓存技术.docx(62页珍藏版)》请在冰豆网上搜索。

java eeWEB缓存技术.docx

javaeeWEB缓存技术

JAVAWeb应用缓存技术资料收集与总结

——作者:

夏俊时间:

2011-1-2

WEB用户行为分析系统上线,在测试某些功能时候,发现部分功能响应时间过长,比如对起点文学的按月的统计数据显示,响应时间超过了3秒,这个不太符合用户的需要,那么接下来就是优化系统,提高系统速度的工作。

我们在分析响应速度缓慢的原因,发现还是数据库处理数据这块原因,究其根本还是数据量过大的原因,而且在数据库层面已经速度这块很难再有提升,因此考虑到web的缓存技术,这些响应速度缓慢的功能基本都是按周,按月的统计数据,因此在单位时间内的缓存是完全可以实现,以下就是我收集的javaweb缓存的相关技术,有两个技术重点推荐,一个是OSCache,一个是JCS,这两个是缓存技术里应用最为广泛的,也是最为成熟并且是开源的技术。

下面是我推荐这两种技术的原因,如下:

1)都是开源的JAVA程序

2)网上能找到比较丰富的资料

3)都支持分布式的系统

4)操作部署都不太难

5)均符合我们现在系统开发的需要

OSCACHE和JCS区别在哪里了?

现在我都只是简单看了下,现在总结还不全面,等具体操作后会加以补充:

1)OSCache我找到的资料,我感觉主要是是页面级的缓存,他的缓存开发代码基本都是在页面里,用标签定义,应该数据都是缓存在客户端(这点还要细细体味)

2)JCS是服务端的缓存,他基本是将需要缓存的数据先存在服务器的内存或是硬盘里,在一定时间内用户可以不通过数据库这个线路获取数据,而是从服务器直接获取,但这样会不会服务端负荷过大

从以上区别来说,如果数据能在客户端缓存,我还是更加推荐点,但是客户端如果缓存,用户要是有什么原因经常清理客户端缓存也是个问题。

最后这几种缓存技术和我们现在系统的整合的问题,这个我还要接着找下数据,我们系统是struts2+jquery(service和DAO层,这个缓存应该不会牵涉到),JCS是服务端缓存,所以数据返回可以在action里封装,对于前台而言影响不大,至于OSCache,如果使用它那么系统该如何改造,这个我要考虑下。

再有就是何时来缓存数据,就是触发缓存的方式,是用户的第一次在适当时间的点击还是通过调度的方式定时缓存了,这点也要考虑下。

写以上内容发现自己刚才对OSCache没有理解太清楚,OSCache缓存是使用标签的,在标签里的内容就会按时间缓存。

因此实际操作下是很重要的。

(一)第一份资料—JCS

Java缓存系统(JavaCachingSystem,JCS)

a)资料编号NO101

JCS概述:

JCS是一个用Java语言编写的缓存系统,可以使用它来创建Java桌面和Web应用程序。

它提供了在缓存器中存储数据、从缓存器中删除数据等方便机制。

使用JCS可以在各种指定的数据区域中存储缓存数据。

JCS定义了4种类型的核心区域:

内存区域、磁盘区域、外围区域和远程区域。

可以结合使用这些核心区域以在如何存储缓存数据、将缓存数据存储在什么地方等方面获得更大的灵活性。

您可以指定首次使用哪个区域,以及发生故障时转移到哪个区域。

内存区域:

内存区域是一个使用最近最少算法(LeastRecentlyUsed,LRU)的纯内存缓存区域。

当内存缓存区域满时,LRU会首先删除最近最少使用的缓存数据。

这个数据区域执行良好,大多数JCS用户将它指定为最先使用的默认缓存区域。

磁盘区域:

磁盘区域是在Web服务器的文件磁盘上缓存数据。

为了提高性能,JCS在文件磁盘上存储实际缓存数据的同时,会在内存中存储缓存数据键。

在首先使用内存区域的典型JCS配置中,任何无法在内存区域中保存的数据都会写入磁盘区域中。

外围区域:

外围区域提供一种可配置方式来在多台服务器之间分发缓存数据。

缓存数据服务器必须有一个开放的用于侦听的端口,而且必须创建一个套接字连接。

这个区域存在一个潜在问题,因为它不能保证各缓存之间的数据的一致性。

但如果是按计划使用该区域,则不会出现这个问题。

远程区域:

远程区域提供了一个使用远程方法调用(RMI)API的缓存区域。

这个区域使用一台远程服务器处理缓存数据。

这台远程缓存服务器可以被多个JCS客户端应用程序用于存储缓存数据。

一些侦听器被定义用于收集来自客户端和服务器的请求。

这个缓存区域帮助减少串行化和多个连接点的开销。

(JCS的可插入控制器:

JCS通过组合缓存器(CompositeCache)让使用多个区域进行缓存存储变得很简单。

组合缓存器为缓存区域提供了一个可插入控制器。

组合缓存器仔细处理复杂的任务,即确定何时以及如何使用每个缓存区域。

JCS将完成大部分复杂的工作,开发人员只需关心获取和设置缓存。

夏俊备注:

我看了下ibatis缓存机制,内存区域的缓存和磁盘缓存,ibatis也有实现。

JCS配置:

配置JCS就是简单地创建和填充一个cache.ccf文件。

这个文件定义缓存应该使用哪些区域,以及这些区域的属性或选项。

根据应用程序的需求配置这个文件是一种快速扩展缓存的简便方式。

您可以指定许多适合配置的选项和属性来满足需求。

清单1显示的是最基本的cache.ccf文件—一个纯内存缓存配置:

清单1.JCS的基本配置

jcs.default=jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes

jcs.default.cacheattributes.MaxObjects=1000

jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

从清单1中可以看出,该配置文件将内存缓存指定为一个LRUMemoryCache。

还可以看到,内存中能保存的对象的最大数量被设置为1000。

大多数应用程序的缓存系统配置要比清单1中复杂得多。

在清单2的配置中,我在定义自己的区域(OUR_REGION)时使用了一个内存区域和一个磁盘区域:

清单2.在JCS配置中定义的区域

jcs.default=DISK_REGION

jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes

jcs.default.cacheattributes.MaxObjects=1000

jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

jcs.region.OUR_REGION=DISK_REGION

jcs.region.OUR_REGION.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes

jcs.region.OUR_REGION.cacheattributes.MaxObjects=1000

jcs.region.OUR_REGION.cacheattributes.MemoryCacheName=

org.apache.jcs.engine.memory.lru.LRUMemoryCache

jcs.region.OUR_REGION.cacheattributes.UseMemoryShrinker=true

jcs.region.OUR_REGION.cacheattributes.MaxMemoryIdleTimeSeconds=3600

jcs.region.OUR_REGION.cacheattributes.ShrinkerIntervalSeconds=60

jcs.region.OUR_REGION.cacheattributes.MaxSpoolPerRun=500

jcs.region.OUR_REGION.elementattributes=org.apache.jcs.engine.ElementAttributes

jcs.region.OUR_REGION.elementattributes.IsEternal=false

jcs.auxiliary.DISK_REGION=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory

jcs.auxiliary.DISK_REGION.attributes=

org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes

jcs.auxiliary.DISK_REGION.attributes.DiskPath=c:

/jcs/disk_region

jcs.auxiliary.DISK_REGION.attributes.maxKeySize=100000

清单2中的第一行表明该配置将默认区域设置为DISK_REGION。

DISK_REGION是IndexedDiskCacheFactory类型,并且该文件在磁盘上指定为c:

\jcs\disk_region。

清单2中的第二个配置组定义了我自己的区域,我为它添加了一些选项,这种类型的配置(在指定用户定义区域时同时使用内存区域和磁盘区域)是很常见的。

清单2中的第3个配置组定义了一个辅助区域。

JCS有两个依赖项:

concurrent和commons-logging(JCS1.2.7.0之前的版本中,还有两个其他依赖项:

commons-collections和commons-lang)。

(JCS辅助插件:

除了4个核心缓存实现外,JCS还提供了一些辅助插件,它们是区域可以使用的可选插件。

这些辅助插件包括索引磁盘缓存(IndexedDiskCache)、TCP外围缓存(TCPLateralCache)和远程缓存服务器(RemoteCacheServer)。

例如,索引磁盘缓存允许在到达内存阈值时在磁盘上交换项目。

这使得每个区域能更灵活地控制其缓存,提供一种类似于大多数操作系统所使用的虚拟内存的存储方法。

cache.ccf配置文件可以让每个辅助区域满足应用程序的需求。

JCS的基本用法:

学习JCS基础知识的一个好方法是查看API最常用的方法。

最好从初始化区域开始。

初始化JCS缓存区域对象能使您访问大部分所需的常用方法。

清单3初始化JCS对象并获得一个默认缓存区域实例:

清单3.检索默认缓存区域

//InitializetheJCSobjectandgetaninstanceofthedefaultcacheregion

JCScache=JCS.getInstance("default");

检索JCS实例后,可以调用最需要的方法。

put方法将一个新对象放入缓存中。

接下来只需一个key(第一个参数)和一个value(第二个参数)。

清单4显示一个基本示例:

清单4.设置缓存项

//Setup

Stringkey="key0";

Stringvalue="value0";

//Placeanewobjectinthecache

cache.put(key,value);

清单4中的示例使用字符串值作为参数,但是您可以使用任何对象。

检索缓存对象只不过是使用JCS提供的get方法。

清单5显示了一个简单示例。

同样,本例使用了一个字符串参数,但您可以使用任何对象。

清单5.检索缓存项

//Retrieveacachedobject

StringcachedData=(String)cache.get(key);

测试缓存数据的有效性可能是处理缓存系统时需要使用的另一种方法。

在JCS中,没有定义只测试缓存项是否存在的测试缓存方法。

但是get方法的返回值可以帮助您。

清单6显示了一种获得此必要功能的方式:

清单6.测试缓存项的有效性

//Retrieveacachedobject

StringcachedData=(String)cache.get(key);

//Checkiftheretrievalworked

if(cachedData!

=null){

//ThecachedDataisvalidandcanbeused

System.out.println("ValidcachedData:

"+cachedData);

}

最后需要几个用于在使用JCS、缓存项和缓存区域后清除它们的常用缓存实用程序。

JCS提供了一种clear方法,用于从调用的缓存区域中删除所有缓存数据。

此外,还提供了一个remove方法,用于删除指定缓存项。

dispose方法也可以处理初始化的JCS区域。

清单7显示了如何使用这些方法:

清单7.清除缓存区域

//Disposeofaspecificcacheditem

cache.remove(key);

//Disposeofallcachedata

cache.clear();

//Disposeofthecacheregion

cache.dispose();

JCS和Java对象:

JCS优于其他缓存系统(请参阅参考资料)的一个地方是它可以很好地使用对象。

大多数Web应用程序是使用面向对象的方法通过Java技术创建的。

例如,与连续从数据库中逐段检索对象相比,缓存对象使应用程序能够更好地执行。

设计一个简单的面向对象的JCS站点的第一个步骤是创建需要存储的对象。

在本例中,我将开发一个基本blogging站点。

清单8显示了我将使用的BlogObject类:

清单8.BlogObject类

packagecom.ibm.developerWorks.objects;

importjava.io.Serializable;

importjava.util.Date;

publicclassBlogObjectimplementsSerializable{

privatestaticfinallongserialVersionUID=6392376146163510046L;

privateintblogId;

privateStringauthor;

privateDatedate;

privateStringtitle;

privateStringcontent;

publicBlogObject(intblogId,Stringauthor,Datedate,Stringtitle,Stringcontent){

this.blogId=blogId;

this.author=author;

this.date=date;

this.title=title;

this.content=content;

}

publicintgetBlogId(){

returnthis.blogId;

}

publicStringgetAuthor(){

returnthis.author;

}

publicDategetDate(){

returnthis.date;

}

publicStringgetTitle(){

returnthis.title;

}

publicStringgetContent(){

returnthis.content;

}

}

在一个类中表示对象后,接着还需要一个类来管理该对象。

管理器处理所有与blog对象相关的管理和缓存功能。

在本例中,管理器将处理三大任务:

∙检索blog对象

∙在缓存中设置blog对象

∙从缓存中清除blog对象

如清单9所示,getBlog方法检索blog对象。

该方法首先试图从缓存获得blog对象。

如果该对象不在缓存中,它将根据其他机制获取该对象:

清单9.通过blog管理器检索blog对象

publicBlogObjectgetBlog(intid){

BlogObjectblog=null;

try{

blogCache=JCS.getInstance(blogCacheRegion);

blog=(BlogObject)blogCache.get(id);

}catch(CacheExceptionce){

blog=null;

}

if(blog==null){

blog=DatabaseManager.getBlog(id);

this.setBlog(

blog.getBlogId(),

blog.getAuthor(),

blog.getDate(),

blog.getTitle(),

blog.getContent()

);

}

returnblog;

}

在清单9中,我使用一个数据库作为检索blog对象的替代机制。

根据另一种机制检索该对象时,应该将该对象设置为缓存,以便下一次检索可以直接从该缓存获取这个对象。

如清单10所示,setBlog方法将blog对象放在缓存中。

这个方法比较简单,因为它只是使用传入的信息创建一个新的blog对象,然后将这个对象放在缓存中。

清单10.通过blog管理器将blog对象放在缓存中

publicbooleansetBlog(intbId,Stringauthor,Datedate,Stringtitle,Stringcontent){

BlogObjectblog=newBlogObject(bId,author,date,title,content);

try{

blogCache=JCS.getInstance(blogCacheRegion);

blogCache.put(bId,blog);

returntrue;

}catch(CacheExceptionce){

returnfalse;

}

}

如清单11所示,cleanBlog方法要么从缓存中清除一个指定的blog,要么从缓存中清除掉所有blog。

这个方法使用JCS的remove和clear方法来清除缓存对象。

清单11.通过blog管理器从缓存中删除blog对象

publicbooleancleanBlog(intblogId){

try{

blogCache=JCS.getInstance(blogCacheRegion);

blogCache.remove(blogId);

}catch(CacheExceptionce){

returnfalse;

}

returntrue;

}

publicbooleancleanBlog(){

try{

blogCache=JCS.getInstance(blogCacheRegion);

blogCache.clear();

}catch(CacheExceptionce){

returnfalse;

}

returntrue;

}

前面的几个类展示了使用JCS缓存对象是很简单的。

拥有对象管理器并使用简单的对象表示之后,您就获得一种在Web应用程序中处理对象的简单但强大的方法。

缓存元数据

JCS提供了更多方法,向应用程序添加缓存所用的方法只是其中的一小部分。

例如,它提供了收集缓存对象和缓存区域元数据的实用程序。

您可以轻松检索以下内容:

∙缓存键名称

∙创建缓存项的时间

∙缓存可以存在的最长时间

∙缓存过期时间

清单12中的例子显示如何检索缓存项的元数据:

清单12.检索缓存项的元数据

try{

JCSAdminBeanadmin=newJCSAdminBean();

LinkedListlinkedList=admin.buildElementInfo(regionName);

ListIteratoriterator=linkedList.listIterator();

while(iterator.hasNext()){

CacheElementInfoinfo=(CacheElementInfo)iterator.next();

System.out.println("Key:

"+info.getKey());

System.out.println("CreationTime:

"+info.getCreateTime());

System.out.println("MaximumLife(seconds):

"+info.getMaxLifeSeconds());

System.out.println("Expiresin(seconds):

"+info.getExpiresInSeconds());

}

}catch(Exceptione){

}

清单13.检索缓存区域的元数据

try{

JCSAdminBeanadmin=newJCSAdminBean();

LinkedListlinkedList=admin.buildCacheInfo();

ListIteratoriterator=linkedList.listIterator();

while(iterator.hasNext()){

CacheRegionInfoinfo=(CacheRegionInfo)iterator.next();

CompositeCachecompCache=info.getCache();

System.out.println("CacheName:

"+compCache.getCacheName());

System.out.println("CacheType:

"+compCache.getCacheType());

System.out.println("CacheMisses(notfound):

"+compCache.getMissCountNotFound());

System.out.println("CacheMisses(expired):

"+compCache.getMissCountExpired())

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 广告传媒

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1