@aloxc
2017-12-05T06:20:34.000000Z
字数 3757
阅读 522
cache
varnish
1.什么是varnish?
Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前更好。
2.为什么要清理varnish的缓存?
如果一个网页的内容发生了更改,而部署在这个网页前面varnish服务器不知道这个网页已经更改,为了让用户能看到最新的内容,我们需要把旧的varnish缓存清理掉。这样下一个请求就会到后端的web服务器取最新的内容后再缓存起来(当然,这个需要在varnish中进行配置)。
3.如何管理varnish的缓存?
据本人总结,目前有三种方式管理varnish的缓存。在讲解清理缓存之前先交代一点varnish版本对清理缓存命令的影响。
varnish 2.x 中清理缓存的命令是 purge,
varnish 3.x 中清理缓存的命令是 ban,
下面讲解中按varnish 3来讲解,使用的命令是ban,如果你使用的是varnish 2.x,请把命令更换为purge。
假如我们需要刷新缓存的是http://192.168.1.1/cache/1.shtml
3.1.通过varnish的管理端口(varnish启动命令中的-T 后面的数字就是varnish的管理端口)来清理缓存。
基本命令是 ban.url url
使用本方法清理varnish缓存最终需要发送的命令是 ban.url /cache/1.shtml,命令里面不用包含主机域名信息。
使用本方法清理缓存后varnish会返回如下信息,最后的一行200 0表明这次操作是成功的,成功的清理了缓存
Linux,2.6.18-238.el5,x86_64,-smalloc,-smalloc,-hcritbit
Type 'help' for command list.
Type 'quit' to close CLI session.
200 0
3.2 通过varnish的服务端口来清理缓存(一般是80端口)。
基本命令是
BAN URL HTTP/1.1\r\n
Host:host\r\n
Connection: close\r\n\r\n
使用本方法清理varnish缓存最终需要发送的命令是
BAN /cache/1.shtml HTTP/1.1\r\n Host:192.168.1.1\r\n Connection: close\r\n\r\n
使用本方法清理缓存后varnish会返回如下信息(末尾的html代码是在varnish的配置文件中配置的),第一行HTTP/1.1 200 Ban added,信息表明成功的清理缓存
HTTP/1.1 200 Ban added
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 204
Accept-Ranges: bytes
Date: Mon, 20 Aug 2012 07:41:57 GMT
X-Varnish: 1862890931
Age: 0
Connection: close
X-Cache: MISS 115
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>200 Ban added</title>
</head>
<body>
</body>
</html>
3.3 通过http清理varnish缓存,
所需要的就是在http请求头部增加header,具体内容是Cache-Control:no-cache,此方法是模拟用户在浏览中使用CTRL+F5来强制缓存varnish缓存。此方法只要返回的http状态是200 即表明本次操作是成功的,成功的清理了varnish缓存。
以上三种方法,笔者推荐使用第一种,接下来是第二种,其次是第三种。
varnish配置文件部分代码:
acl purge {
"localhost";
"192.168.1.0"/24;
}
sub vcl_recv {
.......................
if (req.request == "BAN") {
if (client.ip !~ purge) {
error 405 "Not allowed.";
}
ban("req.url == " + req.url);
error 200 "Ban added";
}
.......................
}
测试的jsp代码:
<%@page import="org.apache.commons.logging.LogFactory"%>
<%@page import="org.apache.commons.logging.Log"%>
<%@page import="cn.tianya.fw.util.ParamUtil"%>
<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
long curr = System.currentTimeMillis(),lngComposeTime = 0L;
int id = ParamUtil.getIntParameter(request, "id", 0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
response.setDateHeader("Last-Modified", curr);
response.setHeader("Cache-Control", "public");
response.setDateHeader("Expires", curr + 30 * 60 * 1000);
out.clear();
Log log = LogFactory.getLog(this.getClass());
%>
<html>
<head><title>Cache--by aloxc</title></head>
<body>
<h1 style="background: #ccddff">Cache[<font color=red><%=id%></font>] : <%=sdf.format(date)%></h1>
</body>
</html>
使用第一种方法清理缓存的java代码:
socket.connect(new InetSocketAddress("192.168.1.1", 3500),5000);
socket.setSendBufferSize(1000);
socket.setSoTimeout(5000);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream());
baseCMD = "ban"
command = baseCMD + ".url " + url;
writer.println(command);
writer.flush();
while((result = reader.readLine()) != null){
result = result.trim();
System.out.println(result);
if(result.equals("200 0")){
break;
}
}
使用第二种方法清理缓存的java代码:
baseCMD = baseCMD.toUpperCase();
socket.connect(new InetSocketAddress("192.168.1.1", "80"),5000);
socket.setSendBufferSize(1000);
socket.setSoTimeout(5000);
writer = new PrintWriter(socket.getOutputStream());
writer.print(baseCMD + " " + url + " HTTP/1.1\r\n");
writer.print("Host:"+host+"\r\n");
writer.print("Connection: close\r\n\r\n");
writer.flush();
使用第三种方法对应的java代码:
url = "http://" + host + url;
Map<String, String> headers = new HashMap<String, String>();
headers.put("Cache-Control", "no-cache");
HttpUtil.head(url, null, headers, 1000, 600, "utf-8");