您的位置:首页 > 编程语言 > Java开发

java程序清除指定的varnish缓存

2016-01-04 15:57 555 查看
案例: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即可。

好了,下面怎么测试就不用说了吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: