java程序清除指定的varnish缓存

案例:varnish对某个动态页面(a.jsp)进行了缓存,且指定缓存时长为5分钟。如果在这5分钟内a.jsp的数据发生了变化,访问时仍会显示旧数据。直到缓存到期后varnish重新缓存才会显示新数据。这就导致页面不能及时显示更新信息。而且由于缓存时长只是一个估计值,如果设定的太长,则不能及时显示新数据,如果设定的太短,则可能浪费资源。

varnish缓存也可以通过后台管理手动执行命令进行清除,但这显然也不够智能。如果我们能够通过程序自动清除缓存就好了!比如我们在后台添加商品的时候对varnish缓存的商品列表进行清除,再次加载商品列表页面时varnish找不到缓存就会重新请求并缓存新的页面。此时的商品列表就是最新的了。

下面用一个简单的java程序实现对varnish缓存的清除。


首先,在varnish配置文件(默认为default.vcl)中对a.jsp页面进行缓存配置。

sub vcl_recv {

……其他配置信息

if (req.url ~ "^.*/a.jsp$") {
     return (lookup);
}

……其他配置信息

}


sub vcl_fetch {

……其他配置信息

if(req.url ~ "^.*/a.jsp$") {
          set beresp.ttl =
5m;
          return (deliver);
    }

……其他配置信息

}


其次,在varnish配置文件中进行刷新缓存的处理。

#允许刷新缓存的规则
acl purgeallow {
    "127.0.0.1";
    "172.16.15.110";//这个IP地址也可以发起刷新请求
}

sub vcl_recv {

if (req.request == "PURGE") {
         if (!client.ip ~ purgeallow) {
             error 405 "Not allowed";
         }
#转到hit或者miss处理
return (lookup);
     }

}

sub vcl_hit {
     #刷新缓存的请求操作,设置TTL为0,返回处理结果代码
     if (req.request == "PURGE") {
         set obj.ttl = 0s;
error 200 "Purged";
     }
std.log("url hit! the url="+req.url);
#缓存服务器命中后(查找到了) 
     return (deliver);
 }
 
 sub vcl_miss {
     #刷新缓存的请求操作
     if (req.request == "PURGE") {
error 404 "Not in cache";
     }
     std.log("url miss! the url="+req.url);
#缓存服务器没有命中(去后台服务器取)
     return (fetch);
 }


最后,就是写个java程序进行测试了。

import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;

public class PurgeVarnish {
public void purge(String url){
HttpClient client = new HttpClient();
HttpMethod method = new PurgeMethod(url);
//添加头信息告诉服务端可以对Response进行GZip压缩。
//我在varnish配置文件的vcl_hash函数中对Accept-Encoding进行了hash,
//如果请求里面不带Accept-Encoding信息头的话,就找不到varnish中的缓存,导致无法清除缓存。
//vcl_hash函数中对Accept-Encoding进行了hash是因为有些浏览器可能不支持压缩,
//如果他们找到的缓存是被压缩过的,就会导致浏览器无法正确解析返回内容。
method.setRequestHeader("Accept-Encoding", "gzip, deflate");
try {
int status = client.executeMethod(method);
System.out.println("status==="+status);
} catch (IOException e) {
e.printStackTrace();
}finally{
method.releaseConnection();
}
}

public static void main(String[] args) {
PurgeVarnish purgeVarnish = new PurgeVarnish();
purgeVarnish.purge("http://172.16.15.111:1111/a.jsp");
}
}


class PurgeMethod extends HttpMethodBase {
public PurgeMethod() {
super();
setFollowRedirects(true);
}
public PurgeMethod(String url) {
super(url);
setFollowRedirects(true);
}


@Override
public String getName() {
return "PURGE";
}

}


注意我在method.setRequestHeader("Accept-Encoding", "gzip, deflate");这一行上面添加的注释。如果你不想添加这个信息头,只要确保varnish配置文件的val_hash函数中没有对Accept-Encoding进行hash即可。


好了,下面怎么测试就不用说了吧。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值