varnish和squid比较:

优点

varnish 采用了visual page cache技术,所有缓存的数据都是直接从内存读取,而squid从硬盘读取缓存的数据,所以varnish在访问速度方面会更快一些。varnish可以支持更多的并发连接,因为varnish的TCP连接和释放比squid快。varnish可以通过管理端口来整理缓存,使用正则表达式就可以批量清除部分缓存。

缺点:

varnish在高并发状态下,CPU,I/O和内存等资源的开销高于squid。varnish的进程一旦挂起、崩溃或者重启,缓存的数据就会从内存中释放出来,此时的所有请求都会被发送到后端应用程序上,在高并发的情况下,就会给后端服务器造成很大的压力。


1、下载安装

wget https://repo.varnish-cache.org/source/varnish-4.0.3.tar.gz

2、安装依赖包

yum install -y python-docutils ncurses-devel pcre-devel libedit-devel  libtool

3、解压,编译安装

tar xf varnish-4.0.3.tar.gz

cd varnish-4.0.3

./configure --prefix=/usr/local/services/varnish -enable-debugging-symbols -enable-deve loper-warnings 

-enable-dependency-tracking

make && make install

cp ./redhat/varnish.initrc /etc/init.d/varnish  //启动脚本

cp ./redhat/varnish.sysconfig /etc/sysconfig/varnish  //配置文件

cp ./etc/example.vcl /usr/local/services/varnish/var/varnish/default.vcl

cat /usr/local/services/varnish/var/varnish/default.vcl


backend default {      //定义后端的ip和port

    .host = "192.168.1.2";

    .port = "80";

}


启动:

/usr/local/services/varnish/sbin/varnishd -f /usr/local/services/varnish/var/varnish/default.vcl -a 192.168.1.3:80 -T 192.168.224.30:2000 -S secret_file

通过访问192.168.1.3:80,转向后端服务上192.168.1.2:80

wKioL1ekEZiScfasAAL_mMWC-EY785.png



Varnish 处理 HTTP 请求的过程如下
Receive 状态(vcl_recv):也就是请求处理的入口状态,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询);
Lookup 状态:进入该状态后,会在 hash 表中查找数据,若找到,则进入 hit(vcl_hit)状态,否则进入 miss(vcl_miss)状态;
Pass(vcl_pass)状态:在此状态下,会直接进入后端请求,即进入 fetch(vcl_fetch)状态;
Fetch(vcl_fetch)状态:在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储;
Deliver(vcl_deliver)状态:将获取到的数据发给客户端,然后完成本次请求;

注:Varnish4中在vcl_fetch部分略有出入,已独立为vcl_backend_fetch和vcl_backend_response 2个函数;

内置函数(也叫子例程)
vcl_recv:用于接收和处理请求;当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求;
vcl_pipe:此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,并将后端响应原样返回客户端;
vcl_pass:此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,但后端主机的响应并不缓存直接返回客户端;
vcl_hit:在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数;
vcl_miss:在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可用于判断是否需要从后端服务器获取内容;
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用此函数;此hash值将作为varnish中搜索缓存对象的key;
vcl_purge:pruge操作执行后调用此函数,可用于构建一个响应;
vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法;
vcl_backend_fetch:向后端主机发送请求前,调用此函数,可修改发往后端的请求;
vcl_backend_response:获得后端主机的响应后,可调用此函数;
vcl_backend_error:当从后端主机获取源文件失败时,调用此函数;
vcl_init:VCL加载时调用此函数,经常用于初始化varnish模块(VMODs)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用此函数,经常用于清理varnish模块;


命令使用:

varnishadm

(varnishadm -T 192.168.224.30:2000 -S secret_file (远程使用加密登录))

  • load/use/discard VCL programs

  • ban (invalidate) cache content

  • change parameters

  • start/stop worker process


varnishhist

showing the distribution of the last N requests by their processing

Hits are marked with a pipe character ("|"), and misses are marked with a hash character ("#")


varnishncsa

The Request transaction is then scanned for the relevant parts in order to output one log line(请求log)


varnishlog

./varnishlog -g raw -i Backend_health

varnish相关日志


varnishstat

displays statistics from a running varnishd(1) instance


varnishtest

simulate a transaction to provoke a specific behavior


varnishtop

display a ranking of requested documents, clients, user agents, or any other information which is recorded in the log





[root@master varnish]# pwd

/usr/local/services/varnish/var/varnish

[root@master varnish]# cat health_check.vcl 

probe backend_healthcheck {

    .url = "/";

    .interval = 5s;

    .timeout = 3s;

    .window = 10;

    .threshold = 8;

     

    #.request =

    #"GET /favicon.ico HTTP/1.1"

    #"Host: www.xingyaohudong.com"

    #"Connection: close"

    #"Accept-Encoding: foo/bar";

}

[root@master varnish]# cat backends.vcl 

import directors;

include "/usr/local/services/varnish/var/varnish/health_check.vcl";

 

backend d102_app_07 {

    .host = "192.168.224.30";

    .port = "80";

     

    #.first_byte_timeout = 9s;

    #.connect_timeout = 3s;

    #.between_bytes_timeout = 1s;

     

    .probe = backend_healthcheck;

}

 

sub vcl_init {

    new web = directors.random(); //round-robin,fallback

     

    web.add_backend(d102_app_07, 1);

}



[root@master varnish]# cat default.vcl

vcl 4.0;

 

import std;

include "/usr/local/services/varnish/var/varnish/backends.vcl";

 

acl allow_purge_cache {

    "127.0.0.1";

    "10.0.0.0"/8;

    "172.0.0.0"/8;

}

 

sub vcl_recv {

    if (req.method == "PURGE") {

        if (!client.ip ~ allow_purge_cache) {

            return (synth(405, "Not Allowed."));

        }

         

        return (purge);

    }

     

    set req.backend_hint = web.backend();

     

    if (req.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {

        return (pass);

    }

     

    if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {

        unset req.http.cookie;

        return (hash);

    }

     

    if (req.restarts == 0) {

        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.http.Cache-Control ~ "(?i)no-cache") {

        if (!(req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {

            return (purge);

        }

    }

     

    if (req.method != "GET" && 

        req.method != "HEAD" && 

        req.method != "PUT" && 

        req.method != "POST" && 

        req.method != "TRACE" && 

        req.method != "OPTIONS" && 

        req.method != "PATCH" && 

        req.method != "DELETE") {        

        return (pipe);

    }

     

    if (req.method != "GET" && req.method != "HEAD") {

        return (pass);

    }

     

    if (req.http.Authorization) {

        return (pass);

    }

     

    if (req.http.Accept-Encoding) {

        if (req.url ~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$") {

            unset req.http.Accept-Encoding;        

        } elseif (req.http.Accept-Encoding ~ "gzip") {

            set req.http.Accept-Encoding = "gzip";

        } elseif (req.http.Accept-Encoding ~ "deflate") {

            set req.http.Accept-Encoding = "deflate";

        } else {

            unset req.http.Accept-Encoding;

        }

    }

     

    if (req.http.Upgrade ~ "(?i)websocket") {

        return (pipe);

    }

     

    if (!std.healthy(req.backend_hint)) {

        unset req.http.Cookie;

    }

     

    if (req.http.x-pipe && req.restarts > 0) {

        unset req.http.x-pipe;

        return (pipe);

    }

     

    return (hash);

}

 

sub vcl_pipe {

    if (req.http.upgrade) {

        set bereq.http.upgrade = req.http.upgrade;

    }

     

    return (pipe);

}

 

sub vcl_pass {

    if (req.method == "PURGE") {

        return (synth(502, "PURGE on a passed object."));

    }

}

 

sub vcl_hash {

    hash_data(req.url);

     

    if (req.http.host) {

        hash_data(req.http.host);

    } else {

        hash_data(server.ip);

    }

     

    if (req.http.Cookie) {

        hash_data(req.http.Cookie);

    }

     

    if (req.http.Accept-Encoding ~ "gzip") {

        hash_data("gzip");

    } elseif (req.http.Accept-Encoding ~ "deflate") {

        hash_data("deflate");

    }

}

 

sub vcl_hit {

    if (req.method == "PURGE") {

        return (synth(200, "Purged."));

    }

     

    if (obj.ttl >= 0s) {

        return (deliver);

    }

     

    if (std.healthy(req.backend_hint)) {

        if (obj.ttl + 10s > 0s) {

            return (deliver);

        } else {

            return(fetch);

        }

    } else {

        if (obj.ttl + obj.grace > 0s) {

            return (deliver);

        } else {

            return (fetch);

        }

    }

     

    return (deliver);

}

 

sub vcl_miss {

    if (req.method == "PURGE") {

        return (synth(404, "Purged."));

    }

     

    return (fetch);

}

 

sub vcl_backend_response {

    set beresp.grace = 5m;

     

    set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*s-maxage=([0-9]+).*", "\1") + "s", 0s);

    if (beresp.ttl > 0s) {

        unset beresp.http.Set-Cookie;

    }

     

    if (beresp.http.Set-Cookie) {

        set beresp.uncacheable = true;

        return (deliver);

    }

     

    if (beresp.http.Cache-Control && beresp.ttl > 0s) {

        set beresp.grace = 1m;

        unset beresp.http.Set-Cookie;

    }

     

    if (beresp.http.Content-Length ~ "[0-9]{8,}") {

        set bereq.http.x-pipe = "1";

        return (retry);

    }

     

    if (bereq.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {

        set beresp.uncacheable = true;

        return (deliver);

    }

     

    if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {

        unset beresp.http.set-cookie;

    }

     

    if (bereq.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {

        unset beresp.http.set-cookie;

        set beresp.do_stream = true;

        set beresp.do_gzip = false;

    }

     

    if ((!beresp.http.Cache-Control && !beresp.http.Expires) || 

         beresp.http.Pragma ~ "no-cache" || 

         beresp.http.Cache-Control ~ "(no-cache|no-store|private)") {

        set beresp.ttl = 120s;

        set beresp.uncacheable = true;

        return (deliver);

    }

     

    if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {

        set beresp.ttl = 120s;

        set beresp.uncacheable = true;

        return (deliver);

    }

     

    if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") {

        set beresp.ttl = 15m;

    } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {

        set beresp.ttl = 30m;

    } else {

        set beresp.ttl = 10m;

    }

     

    return (deliver);

}

 

sub vcl_purge {

    if (req.method != "PURGE") {

        set req.http.X-Purge = "Yes";

        return (restart);

    }

}

 

sub vcl_deliver {

    if (obj.hits > 0) {

        set resp.http.X-Cache = "HIT from " + req.http.host;

        set resp.http.X-Cache-Hits = obj.hits;

    } else {

        set resp.http.X-Cache = "MISS from " + req.http.host;

    }

     

    unset resp.http.X-Powered-By;

    unset resp.http.Server;

     

    unset resp.http.Via;

    unset resp.http.X-Varnish;

     

    unset resp.http.Age;

}

 

sub vcl_backend_error {

    if (beresp.status == 500 || 

        beresp.status == 501 || 

        beresp.status == 502 || 

        beresp.status == 503 || 

        beresp.status == 504) {

        return (retry);

    }

}

 

sub vcl_fini {

    return (ok);

}


wKioL1ekZXyD_sCrAAEgB4E9KEs153.png