[关闭]
@aloxc 2017-12-05T06:20:34.000000Z 字数 3757 阅读 522

varnish purge缓存清理技术总结(附相关的代码)

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表明这次操作是成功的,成功的清理了缓存

200 203

Varnish Cache CLI 1.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,信息表明成功的清理缓存

  1. HTTP/1.1 200 Ban added
  2. Content-Type: text/html; charset=utf-8
  3. Retry-After: 5
  4. Content-Length: 204
  5. Accept-Ranges: bytes
  6. Date: Mon, 20 Aug 2012 07:41:57 GMT
  7. X-Varnish: 1862890931
  8. Age: 0
  9. Connection: close
  10. X-Cache: MISS 115
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html>
  4. <head>
  5. <title>200 Ban added</title>
  6. </head>
  7. <body>
  8. </body>
  9. </html>

3.3 通过http清理varnish缓存,
所需要的就是在http请求头部增加header,具体内容是Cache-Control:no-cache,此方法是模拟用户在浏览中使用CTRL+F5来强制缓存varnish缓存。此方法只要返回的http状态是200 即表明本次操作是成功的,成功的清理了varnish缓存。

以上三种方法,笔者推荐使用第一种,接下来是第二种,其次是第三种。

varnish配置文件部分代码:

  1. acl purge {
  2. "localhost";
  3. "192.168.1.0"/24;
  4. }
  5. sub vcl_recv {
  6. .......................
  7. if (req.request == "BAN") {
  8. if (client.ip !~ purge) {
  9. error 405 "Not allowed.";
  10. }
  11. ban("req.url == " + req.url);
  12. error 200 "Ban added";
  13. }
  14. .......................
  15. }

测试的jsp代码:

  1. <%@page import="org.apache.commons.logging.LogFactory"%>
  2. <%@page import="org.apache.commons.logging.Log"%>
  3. <%@page import="cn.tianya.fw.util.ParamUtil"%>
  4. <%@page import="java.util.Date"%>
  5. <%@page import="java.text.SimpleDateFormat"%>
  6. <%@ page language="java" contentType="text/html; charset=UTF-8"
  7. pageEncoding="UTF-8"%>
  8. <%
  9. long curr = System.currentTimeMillis(),lngComposeTime = 0L;
  10. int id = ParamUtil.getIntParameter(request, "id", 0);
  11. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  12. Date date = new Date();
  13. response.setDateHeader("Last-Modified", curr);
  14. response.setHeader("Cache-Control", "public");
  15. response.setDateHeader("Expires", curr + 30 * 60 * 1000);
  16. out.clear();
  17. Log log = LogFactory.getLog(this.getClass());
  18. %>
  19. <html>
  20. <head><title>Cache--by aloxc</title></head>
  21. <body>
  22. <h1 style="background: #ccddff">Cache[<font color=red><%=id%></font>] : <%=sdf.format(date)%></h1>
  23. </body>
  24. </html>

使用第一种方法清理缓存的java代码:

  1. socket.connect(new InetSocketAddress("192.168.1.1", 3500),5000);
  2. socket.setSendBufferSize(1000);
  3. socket.setSoTimeout(5000);
  4. reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  5. writer = new PrintWriter(socket.getOutputStream());
  6. baseCMD = "ban"
  7. command = baseCMD + ".url " + url;
  8. writer.println(command);
  9. writer.flush();
  10. while((result = reader.readLine()) != null){
  11. result = result.trim();
  12. System.out.println(result);
  13. if(result.equals("200 0")){
  14. break;
  15. }
  16. }

使用第二种方法清理缓存的java代码:

  1. baseCMD = baseCMD.toUpperCase();
  2. socket.connect(new InetSocketAddress("192.168.1.1", "80"),5000);
  3. socket.setSendBufferSize(1000);
  4. socket.setSoTimeout(5000);
  5. writer = new PrintWriter(socket.getOutputStream());
  6. writer.print(baseCMD + " " + url + " HTTP/1.1\r\n");
  7. writer.print("Host:"+host+"\r\n");
  8. writer.print("Connection: close\r\n\r\n");
  9. writer.flush();

使用第三种方法对应的java代码:

  1. url = "http://" + host + url;
  2. Map<String, String> headers = new HashMap<String, String>();
  3. headers.put("Cache-Control", "no-cache");
  4. HttpUtil.head(url, null, headers, 1000, 600, "utf-8");

x

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注