页面片段缓存方案介绍(OSCache,Velocity自定义标签,Varnish+ESI)

1.OSCache

OSCache是一个使用较多的高性能J2EE缓存框架,适用于任何JAVA应用程序的普通缓存解决方案。可以不受限制的缓存部分jsp页面或http请求;支持永久缓存,将缓存内存随意写入硬盘;支持集群-集群缓存数据,而不需要修改代码;控制缓存对象过期时间,可插入式刷新策略;

oscache-2.1.jar;commons-logging-api-1.1.jar;log4j-1.2.11.jar

配置OSCache环境

CacheFilter只对http 200的页面请求做处理,不对其他状态做缓存处理

web.xml

<!—osCacheFilter --> <filter> <filter-name>osCacheFilter</filter-name> <filter-class> com.opensymphony.oscache.web.filter.CacheFilter </filter-class> <init-param> <param-name>time</param-name> <param-value>60</param-value> </init-param> <init-param> <param-name>scope</param-name> <param-value>session</param-value> </init-param> </filter> <filter-mapping> <filter-name>osCacheFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>  

 

oscache.properties

#缓存到内存,如果设置成false cache.memory=true #不使用无限硬盘空间 cache.unlimited.disk=false #缓存持久化实现类,磁盘持久化监听器 cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener #缓存磁盘路径,以后注意观察该目录生成的内容 cache.path=D://OSCache//cache #选择一种缓存算法,还可选 FIFOCache、UnlimitedCache cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCacheache.base.algorithm.LRUCache #cache.cluster为集群相关设置信息 #cache.cluster.multicast.ip为广播IP地址 #cache.cluster.properties为集群属性  

 

目前新版本的OSCache已经支持集群分布式

实现分布式环境消息同事,目前比较流行的2中做法:1.JavaGroups[http://www.jgroups.org/];2.JMS   这2种底层都实现了广播通信。

采用javaGroup,我们可以看下官方文档,使用下面的方式配置

#cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListener #cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;/ mcast_send_buf_size=150000;mcast_recv_buf_size=80000):/ PING(timeout=2000;num_initial_members=3):/ MERGE2(min_interval=5000;max_interval=10000):/ FD_SOCK:VERIFY_SUSPECT(timeout=1500):/ pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):/ UNICAST(timeout=300,600,1200,2400):/ pbcast.STABLE(desired_avg_gossip=20000):/ FRAG(frag_size=8096;down_thread=false;up_thread=false):/ pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true) #cache.cluster.multicast.ip=231.12.21.132   

拷贝oscache.tld到WEB-INF下

 

//index.jsp,用来刷新指定页面缓存

 <cache:flush key="newsinfo1" scope="session"></cache:flush>

 

 

 

 

//newinfo.jsp  页面缓存内容

 <cache:cache key="newsinfo1" duration="120s" scope="application"> <br><%=new Date() %><br> </cache:cache>

 

 

 

 

cache标签(其他属性使用可以在官方文档上查阅或者http://praguesky.blog.163.com/blog/static/232970042007415731504/)
        这是OSCache提供的标签库中最重要的一个标签,包括在标签中的内容将应用缓存机制进行处理,处理的方式将取决于编程者对cache标签属性的设置。
        第一次请求到达时,标签中的内容被处理并且缓存起来,当下一个请求到达时,缓存系统会检查这部分内容的缓存是否已经失效,主要是以下几项:
        (1)缓存时间超过了cache标签设置的time或者duration属性规定的超时时间
        (2)cron属性规定的时间比缓存信息的开始时间更晚
        (3)标签中缓存的内容在缓存后又被重新刷新过
        (4)其他缓存超期设定
        如果符合上面四项中的任何一项,被缓存的内容视为已经失效,这时被缓存的内容将被重新处理并且返回处理过后的信息,如果被缓存的内容没有失效,那么返回给用户的将是缓存中的信息。
        cache标签的常用属性说明:

key

标识缓存内容的关键词。在指定的作用范围内必须是唯一的。默认的key是被访问页面的URI和后面的请求字符串。可以在同一个页面中使用很多cache标签而不指定他的key属性,这种情况下系统使用该页面的URI和后面的请求字符串,另外再自动给这些key增加一个索引值来区分这些缓存内容。但是不推荐采用这样的方式。

scope

缓存发生作用的范围,可以是application或者session。默认为application。

time

缓存内容的时间段,单位是秒,默认是3600秒,也就是一个小时,如果设定一个负值,那么这部分被缓存的内容将永远不过期。

duration

指定缓存内容失效的时间,是相对time的另一个选择,可以使用简单日期格式或者符合USO-8601的日期格式。如:duration='PT5M' duration='5s'等。

cron

指定缓存内容失效表达式,见“Cron表达式基本语法”。

refresh

false 或者true。如果refresh属性设置为true,不管其他的属性是否符合条件,这部分被缓存的内容都将被更新,这给编程者一种选择,决定什么时候必须刷新。

mode

如果不希望被缓存的内容增加到给用户的响应中,可以设置mode属性为"silent"。此时被缓存的部分不在页面上显示,而其它任意的mode属性值都会将缓存的部分显示到页面上。

groups

指定当前cache标签所属的组,可使用“,”分割组名。这样就可以对缓存项进行分组了。如果缓存项依赖于应用的其它部分或其它数据,分组就有了用武之地——当这种依赖改变时(刷新相关的组),这个组的所有缓存项都将过期。

language

使用ISO-639定义的语言码来发布不同的缓存内容(under an otherwise identical key)。要在一个多语言网站上同一段JSP代码不同用户的参数提供不同的语言时,这个属性会很有用。

refreshpolicyclass

指定自定义的刷新策略类的全限定类名。这个类继承自com.opensymphony.oscache.web.WebEntryRefreshPolicy

refreshpolicyparam

指定任意需要传给refreshpolicyclass的参数。如果没有指定refreshpolicyclass,则这个值不起作用。

这些属性可以单独使用,也可以根据需要组合使用。

 

2.Velocity

http://news.cnblogs.com/n/100285/

 

3.Varnish+ESI

页面片段缓存方案介绍(OSCache,Velocity自定义标签,Varnish+ESI)_第1张图片

varnish安装

wget http://repo.varnish-cache.org/source/varnish-2.1.5.tar.gz
tar xzvf varnish-2.1.5.tar.gz
./configure -prefix=/usr/local/varnish
make
make install

如果提示缺少 'libpcre'

yum -y install automake autoconf libtool ncurses-devel libxslt groff pcre-devel pkgconfig

varnish自己并没有提供服务,只是一个缓存服务器(Squid???)

Varnish的默认配置文件在/usr/local/varnish/etc/varnish/default.vcl(这个配置文件指示所使用的后端服务器)

backend default { .host = "127.0.0.1"; .port = "8080"; }  

./sbin/varnishd -a 0.0.0.0:80 -f /usr/local/varnish/ect/varnish/default.vcl -s malloc,500M
sub vcl_recv{
   #...
   #做一些处理,如req.request="GET"的时候用lookup查找缓存
   #...
   return (lookup);
}
sub vcl_fetch{
   if(req.url == "/welcome.jsp"){
     return (pass);
   }
   if(req.url == "/esi.jsp"){
    esi;    
   }
} 
//welcome.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%=new Date() %> 
//esi.jsp
<esi:include src="/oscache_test/welcome.jsp" mce_src="oscache_test/welcome.jsp"/>
<br/>
<esi:include src="http://10.20.150.211:8989/oscache_test/welcome.jsp" mce_src="http://10.20.150.211:8989/oscache_test/welcome.jsp" />
<br/>
<esi:include src="http://10.19.6.22:8080/oscache_test/welcome.jsp" mce_src="http://10.19.6.22:8080/oscache_test/welcome.jsp" /> 
对于<esi:include src="http://192.168.0.100:8080/oscache_test/welcome.jsp"/>在这种情况varnish会做esi解析,但没有缓存下来

varnish将所有的object存于一个单独的大文件中,在工作进程初始化时候这个文件就会被加载到内存中。varnish在内存中的实现和“文件系统”有点相似,具有分配、释放、修剪、合并等功能;这种设计避免了软件与系统对内存控制的冲突;像squid、oscache会将每个object存在一个小文件,相对来说,varnish的大文件可以减少文件系统频繁的操作,这就需要记录每个object在内存的偏移量,定期检查释放内存,编程难度增加,却可以提高性能。

ps -aux|grep "varnish"

我们可以看到varnish启动或有2个进程 master(management)进程和child(worker)进程。master读入存储配置命令,进行初始化,然后fork,监控child。child则分配线程进行cache工作,child还会做管理线程和生成很多worker线程。

child进程主线程初始化过程中,将存储大文件整个加载到内存中,如果该文件超出系统的虚拟内存,则会减少原来配置mmap大小,然后继续加载,这时候创建并初始化空闲存储结构体,放在存储管理的struct中,等待分配。

接着,varnish某个负责接口新http连接的线程开始等待用户,如果有新的http连接,但是这个线程只负责接收,然后唤醒等待线程池中的work线程,进行请求处理。

worker线程读入uri后,将会查找已有的object,命中直接返回,没有命中,则会从后端服务器中取出来,放到缓存中。如果缓存已满,会根据LRU算法,释放旧的object。

对于释放缓存,有一个超时线程会检测缓存中所有object的生命周期,如果缓存过期(ttl),则删除,释放相应的存储内存。

存储结构体(定义在varnish/bin/varnishd/strorage_file.c)
struct smf_sc{
    const char *filename;/* 缓存大文件的名称 */
    int  fd;    /*缓存大文件的文件描述符*/
    unsigned   pagesize;/*内存的页面大小,从系统调用getpagesize()获得 */
    uintmax_t    filesize;/*缓存大文件的大小*/
    struct smfhead order;/*内存地址排序的smf尾队列头部*/
    struct smfhead free[NBUCKET];/*空闲的smf尾队列头部,NBUCKET表明的是空闲页面数,大于NBUCKET-1空闲页面的smf,都挂在free[NBUCKET-1]这个尾队列上*/
    struct smfhead used;/*正在被使用的smf*/
    MTX mtx;/*define MTX pthread_mutex_t*/
};
基本结构体,缓存文件中一小块连续的内存,用来分配相应大小的http object(定义在strorage_file.c)
struct smf{
    unsigned magic;/*魔法数字,用来检验结构体是否有效*/
    #define SMF_MAGIC  0X0927a8a0
    struct storage s;/*上层逻辑存储结构体*/
     struct smf_sc *sc;/*smf管理存储结构体*/
    int alloc;/*是否分配完成*/
    off_t size;/*smf大小*/
    off_t offset;/*已经分配过的内存偏移*/
   unsigned char *ptr;/*指向可分配内存的起始地址*/
    VTAILQ_ENTRY(smf)    order;/*按内存地址排序的smf入口*/
   VTAILQ_ENTRY(smf)  status;/**/
   struct smfhead  *flist;/*指向smf_sc中free[n]相应的空闲尾队列头部*/
};

你可能感兴趣的:(struct,cache,object,velocity,application,include)