varnish 中的内置变量

req
repos
client
server
bereq
beresp bereq
bereq.http.HEADER 由varnish发往backend server 的请求报文指定首部
bereq.request 请求方法
bereq.url
bereq.proto: 协议版本 beresp
bereq.proto
bereq.status:
bereq.backend.ip
beresp.backend.name
beresp.http.HEADER 从backend server 响应报文指定首部
bereq.ttl 后端服务器响应的内容的余下的生存时长; 官方文档
http://www.varnish-cache.org/trac/wiki/VCLExampleDirector
支持虚拟主机:
if (req.http.host == "www.fengpic.com") { } 强制对某些资源的请求,不检查缓存:
/admin
/login if (req.url ~ "(?i)^/login" || req.url ~ "(?i)^/admin") {
return(pass)
} test.html
if (req.url ~ "(?i)test.html$") {
return(pass)
} sub vcl_recv{
  if (req.url ~"(?i)\.(jpg|png|gif)$") {
    set req.backend_hint = "fdfs_g1_s1"
  else {
    set req.backend_hint = "fdfs_g1_s2"
    }
  } 对域名进行缓存 sub vcl_recv {
  if (req.http.host ~ "^(ww.)?example.com%") {
    set req.backend_hint = vdir1.backend();
  }
} 对多个group进行缓存

backend fdfs_g1_s1 {
.host = "192.168.20.151";
.port = "8080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = 5;
.threshold = 2;
}
}


backend fdfs_g1_s2 {
.host = "192.168.20.152";
.port = "8080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = 5;
.threshold = 2;
}
}


backend fdfs_g2_s1 {
.host = "192.168.20.153";
.port = "8080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = 5;
.threshold = 2;
}
}


backend fdfs_g2_s2 {
.host = "192.168.20.154";
.port = "8080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = 5;
.threshold = 2;
}
}


sub vcl_init {
new vdir1 = directors.round_robin();
vdir1.add_backend(fdfs_g1_s1);
vdir1.add_backend(fdfs_g1_s2);

new vdir2 = directors.round_robin();
vdir2.add_backend(fdfs_g2_s1);
vdir2.add_backend(fdfs_g2_s2);

return (ok);
}


sub vcl_recv {
  if (req.url ~ "($i)^/group1") {
    set req.backend_hint = vdir1.backend();
  }
  if (req.url ~ "($i)^/group2") {
    set req.backend_hint = vdir2.backend();
  }
}


首先是必须定义版本号: vcl 4.0。VMOD’s更独立化,官方推荐是加载Standard VMOD’s(std)。

另外director已变为VMOD,如需使用,需要import directors。

vcl_fetch函数被vcl_backend_response和vcl_backend_fetch代替,且req.*不再适用vcl_backend_response,只能使用bereq.*。

至于vcl_backend_fetch貌似没哪个doc见到详细用法。

error变更为return(synth(http_code,message)),req.backend成了req.backend_hint,req.request变更为req.method,obj为只读对象了。

vcl_synth采用resp.*,而非原来的obj.*。

vcl_error变更为vcl_backend_error,必须使用beresp.*,而不是obj.*。

关键字"purge;"命令,已被去除。在vcl_recv使用return(purge)。

hit_for_pass通过set beresp.uncacheable = true;来指定。

vcl_recv必须将lookup变更返回hash,vcl_hash必须将hash变更返回lookup,vcl_pass必须将pass变更返回fetch。

req.backend.healty被std.healthy(req.backend)代替,但是设置不了grace,鸡肋,被抛弃了,现在仅能做的就是keepalive的作用了。

req、bereq,resp、beresp之间不同,可被使用的位置不同。

server.port、client.port分别变更为std.port(server.ip)、std.port(client.ip),跟上面healthy一样,需要import std。

session_linger变更为timeout_linger,sess_timeout变更为timeout_idle,sess_workspace被抛弃了。

remove被完全弃用了,不过我一直用unset的说。

return(restart)变更为return(retry),vcl_backend_fetch会被使用到。

自定义sub函数不能以vcl_开头,调用方式call udf。
 vcl 4.0;

 import std;
import directors; backend fdfs_g1_s1 {
.host = "192.168.20.151";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} backend fdfs_g1_s2 {
.host = "192.168.20.152";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} acl purgers {
"localhost";
"127.0.0.1";
} sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(fdfs_g1_s1);
vdir.add_backend(fdfs_g1_s2);
return (ok);
} sub vcl_recv { set req.backend_hint = vdir.backend(); if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
} if (req.method == "PURGE") { # PURGE请求的处理
if (!client.ip ~ purgers) {
return(synth(,"Method not allowed"));
}
#清理缓存
return (purge);
}
# 禁止缓存的文件
if (req.url ~ "\.(php|jsp|do|cgi)$") {
return (pass);
} if (req.method == "PRI") {
#/* We do not support SPDY or HTTP/2.0 */
return (synth());
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
#/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
} if (req.method != "GET" && req.method != "HEAD") {
#/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
#/* Not cacheable by default */
return (pass);
}
return (hash);
} sub vcl_backend_response { if (beresp.http.cache-control !~ "s-maxage") {
if (bereq.url ~ "\.(gif|jpeg|jpg|png)$") {
set beresp.ttl = 3600s;
unset beresp.http.set-cookie;
} if (bereq.url ~ "\.(css|js)$") {
set beresp.ttl = 600s;
unset beresp.http.set-cookie;
} if (bereq.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|amr|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|xz|zip)(\?.*)?$") {
unset beresp.http.set-cookie;
set beresp.do_stream = true;
set beresp.do_gzip = false;
}
} else {
if (beresp.ttl > 0s) {
unset beresp.http.Set-Cookie;
}
} if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-control ~ "no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "no-cache|no-store|private") || beresp.http.Vary == "*") {
set beresp.ttl = 120s;
set beresp.uncacheable = true;
} return (deliver);
} sub vcl_backend_fetch {
return (fetch);
} sub vcl_pipe {
# By default Connection: close is set on all piped requests, to stop
# connection reuse from sending future requests directly to the
# (potentially) wrong backend. If you do want this to happen, you can undo
# it here.
# unset bereq.http.connection;
return (pipe);
} sub vcl_pass {
return (fetch);
} sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
} sub vcl_purge {
return (synth(, "Purged"));
} sub vcl_hit {
if (obj.ttl >= 0s) {
#// A pure unadultered hit, deliver it
return (deliver);
}
if (obj.ttl + obj.grace > 0s) {
#// Object is in grace, deliver it
#// Automatically triggers a background fetch
return (deliver);
}
#// fetch & deliver once we get the result
return (miss);
} sub vcl_miss {
return (fetch);
} sub vcl_deliver {
set resp.http.Via = "cache";
unset resp.http.X-Varnish;
set resp.http.Server="cache-server";
unset resp.http.Age;
# set resp.http.x-hits = obj.hits; if (obj.hits > ) {
set resp.http.X-Cache = "Hit aaaaaa CDN";
}else {
set resp.http.X-Cache = "Miss";
}
return (deliver);
} sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + resp.status + " " + resp.reason + {"</title>
</head>
<body>
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + req.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
} sub vcl_backend_error {
set beresp.http.Content-Type = "text/html; charset=utf-8";
set beresp.http.Retry-After = "";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + beresp.status + " " + beresp.reason + {"</title>
</head>
<body>
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
<p>"} + beresp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + bereq.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
} sub vcl_fini {
return (ok);
}
 vcl 4.0;

 import std;
import directors; backend fdfs_g1_s1 {
.host = "192.168.20.151";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} backend fdfs_g1_s2 {
.host = "192.168.20.152";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} backend fdfs_g2_s1 {
.host = "192.168.20.113";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} backend fdfs_g2_s2 {
.host = "192.168.20.115";
.port = "";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 10s;
.window = ;
.threshold = ;
}
} acl purgers {
"localhost";
"127.0.0.1";
} sub vcl_init {
new g1vdir = directors.round_robin();
g1vdir.add_backend(fdfs_g1_s1);
g1vdir.add_backend(fdfs_g1_s2); new g2vdir = directors.round_robin();
g2vdir.add_backend(fdfs_g2_s1);
g2vdir.add_backend(fdfs_g2_s2); return (ok);
} sub vcl_recv { if (req.url ~ "/group1") {
set req.backend_hint = g1vdir.backend();
} if (req.url ~ "/group2") {
set req.backend_hint = g2vdir.backend();
} if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
} if (req.method == "PURGE") { # PURGE请求的处理
if (!client.ip ~ purgers) {
return(synth(,"Method not allowed"));
}
#清理缓存
return (purge);
}
# 禁止缓存的文件
if (req.url ~ "\.(php|jsp|do|cgi)$") {
return (pass);
} if (req.method == "PRI") {
#/* We do not support SPDY or HTTP/2.0 */
return (synth());
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
#/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
} if (req.method != "GET" && req.method != "HEAD") {
#/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
#/* Not cacheable by default */
return (pass);
}
return (hash);
} sub vcl_backend_response { if (beresp.http.cache-control !~ "s-maxage") {
if (bereq.url ~ "\.(gif|jpeg|jpg|png)$") {
set beresp.ttl = 3600s;
unset beresp.http.set-cookie;
} if (bereq.url ~ "\.(css|js)$") {
set beresp.ttl = 600s;
unset beresp.http.set-cookie;
} if (bereq.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|amr|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|xz|zip)(\?.*)?$") {
unset beresp.http.set-cookie;
set beresp.do_stream = true;
set beresp.do_gzip = false;
}
} else {
if (beresp.ttl > 0s) {
unset beresp.http.Set-Cookie;
}
} if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-control ~ "no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "no-cache|no-store|private") || beresp.http.Vary == "*") {
set beresp.ttl = 120s;
set beresp.uncacheable = true;
} return (deliver);
} sub vcl_backend_fetch {
return (fetch);
} sub vcl_pipe {
# By default Connection: close is set on all piped requests, to stop
# connection reuse from sending future requests directly to the
# (potentially) wrong backend. If you do want this to happen, you can undo
# it here.
# unset bereq.http.connection;
return (pipe);
} sub vcl_pass {
return (fetch);
} sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
} sub vcl_purge {
return (synth(, "Purged"));
} sub vcl_hit {
if (obj.ttl >= 0s) {
#// A pure unadultered hit, deliver it
return (deliver);
}
if (obj.ttl + obj.grace > 0s) {
#// Object is in grace, deliver it
#// Automatically triggers a background fetch
return (deliver);
}
#// fetch & deliver once we get the result
return (miss);
} sub vcl_miss {
return (fetch);
} sub vcl_deliver {
set resp.http.Via = "cache";
unset resp.http.X-Varnish;
set resp.http.Server="cache-server";
unset resp.http.Age;
# set resp.http.x-hits = obj.hits; if (obj.hits > ) {
set resp.http.X-Cache = "Hit aaaaaa CDN";
}else {
set resp.http.X-Cache = "Miss";
}
return (deliver);
} sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + resp.status + " " + resp.reason + {"</title>
</head>
<body>
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + req.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
} sub vcl_backend_error {
set beresp.http.Content-Type = "text/html; charset=utf-8";
set beresp.http.Retry-After = "";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + beresp.status + " " + beresp.reason + {"</title>
</head>
<body>
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
<p>"} + beresp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + bereq.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
} sub vcl_fini {
return (ok);
}

varnish4.0 流程图以及说明的更多相关文章

  1. varnish4.0缓存代理配置

    防伪码:你必须非常努力,才能看起来毫不费力. 一.varnish原理: 1)Varnish简介: varnish缓存是web应用加速器,同时也作为http反向缓存代理.你可以安装varnish在任何h ...

  2. 编译安装 varnish-4.1.2和yum 安装 varnish-4.0.3

    vanish可以让用户自己选择缓存数据是存于内存还是硬盘,存于内存一般基于二八法则即常访问的数据是磁盘存储的总数据五分之一,因此内存也应该是硬盘文件大概五分之一.如果有多台vanish则,总内存满足即 ...

  3. varnish4.0简介

    Varnish 4.0 简介 Varnish 是一款开源的HTTP加速器和反向代理服务器,它的主要特点有: (1)是基于内存缓存,重启后数据将消失.(2)利用虚拟内存方式,io性能好.(3)支持设置0 ...

  4. OAuth2.0流程图

    OAuth2.0是用户验证和授权标准

  5. Varnish 4.0 实战(转)

    简介 Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高.速度更快.管 ...

  6. varnish 4.0编译安装小记

    varnish 4.0 编译问题 centos-6.5 x86环境 装varnish遇到几个错误要先安装python-docutils然后提示error1,于是安装:libedit-devel然后提示 ...

  7. Activiti工作流学习-----基于5.19.0版本(7)

    八.BPMN 2.0流程图详解 BPMN 2.0的标准的出现是好事,用户不在被某个工作流开发商绑架或者在工作流中开发妥协,Activiti作为BPMN标准的一套解决方案,使得用户在选择工作流框架时可以 ...

  8. Varnish 4.0

    Varnish 4.0 实战   简介 Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varn ...

  9. OAuth2.0的原理介绍

    OAuth2.0是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. OAuth2.0(开放授权)是一个正式的互联网标准协议. 允许第三方网站在用户 ...

随机推荐

  1. [转载]memcached完全剖析--1. memcached的基础

    转载自:http://charlee.li/memcached-001.html 翻译一篇技术评论社的文章,是讲memcached的连载.fcicq同学说这个东西很有用,希望大家喜欢. 发表日:200 ...

  2. [Android]Android开发入门之HelloWorld

    引言:在做Unity开发的时候,发现这么个问题,虽然Unity是跨平台的,能够进行Android,IOS,Web,PC等开发,但如果要实现一些稍微系统层的东西,还是需要通过通信,调用原系统的接口(自定 ...

  3. 同一台机子上用多个git 账号

    Step 1 - Create a New SSH Key We need to generate a unique SSH key for our second GitHub account. 1 ...

  4. activity 、window与view的关系 (上)

    我在研究任玉刚老师的<android开发艺术探索>的关于windowmanager那一章时,我发现自己对于acitivity.window和view之间的概念还是比较模糊. 然后查了一下a ...

  5. Ubuntu下使用vsftpd实现FTP

    ## 哈哈哈啊哈 被领导啪啪啪打脸,文件连在线打开都不行,你做事情的时候有没有考虑过别人使用时的感受!! 需求: 部门老大希望在内网搭建一个用于员工共享文件的系统. 很自然的就想到通过FTP去实现. ...

  6. ZeroMQ接口函数之 :zmq_close - 关闭ZMQ socket

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_close zmq_close(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_close  ...

  7. [IOS初学]ios 第一篇 storyboard 与viewcontroller的关系

    学习了一下ios,把一个基本的概念搞清楚了,在android或者wp中,大家基本都是习惯与一个画面场景代表一个类,新建场景的时候自动新建了类,但在ios中使用了storyboard之后发现,在stor ...

  8. istringstream的操作

    今天在stackoverflow上看到这么个问题,写完之后看了看别人的提交的答案,感觉自己的答案虽然能得出正确结果但是有点啰嗦,对于c++还是没有熟练,没有想起有istringstream,而且提问的 ...

  9. Spring基础学习笔记-Bean的基础知识

    一. Bean的定义,初始化,使用和销毁 二.ref指定依赖的三种模式 三.Bean的五种自动装配模式(autowire) 四.Bean依赖检查的4种模式:配合atuowire使用,dependenc ...

  10. JavaScript 实现彩票中随机数组的获取

    1.效果图: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...