varnish

varnish:

varnish是一个Web应用程序加速器也被称为高速缓存HTTP反向代理。可以在HTTP的任何服务器的前端安装它并将其配置为缓存服务器。varnish加速明显,它通常加速到300- 1000倍,当然这也取决于你的架构。varnish的主要特点,除了它的性能,还有就是它的配置语言,VCL的灵活性。
varnish架构:


varnish_第1张图片

图上显示了Varnish架构的框图。该图显示了数据流在varnish的主要部分之间。
主程序段是Manager进程,它包含在varnishd二进制程序中。该Manager进程的任务是将任务(包括缓存)委派给子进程。Manager过程确保每个任务总是有一个进程。
Manar的命令行界面(CLI)可通过以下方式访问:1)varnishadm,如解释中所述管理界面varnishadm部分,2)varnish代理vagent2,或 varnish管理控制台(VAC(通过vagent2)。

HTTP请求处理基本流程:
varnish_第2张图片
Varnish处理HTTP请求的过程如下:

Receive(vcl_recv)状态:也就是请求处理的入口状态,根据VCL规则判断该请求是应该进入 pass(vcl_pass)或者是 pipe(vcl_pipe)或者是lookup(缓存本地查询),还是purge(vcl_purge)。
Lookup 状态:进入该状态后,会在hash表中查找数据。若找到,则进入hit(vcl_hit)状态,否则进入miss(vcl_miss)状态。
Pass(vcl_pass)状态:在此状态下,对于请求会直接发往后端主机,进入到ackend_fetch(vcl_backend_fetch)状态。
Backend_Fetch(vcl_backend_fetch)状态:在此状态下,对请求会向后端服务器进行获取,发送请求,获得数据,并根据配置文件中对此类数据的缓存设置进行缓存或者其他操作。
Deliver(vcl_deliver)状态:将获取到的数据发送给客户端,完成本次请求。

内置函数

vcl_recv:用于接收和处理请求;当请求到达varnish,通过判断请求的数据来决定如何处理请求
vcl_pipe:用于将请求直接传递至后端主机,并将后端响应原封不动返回给客户端
vcl_pass:用于将请求直接传递给后端主机,但后端主机的响应并不缓存,而是直接返回给客户端
vcl_hit:在缓存中找到请求的内容后自动调用
vcl_miss:在缓存中没有找到请求的内容后自动调用。用于判断是否需要从后端服务器获取内容
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用。此hash值将作为varnish中hash表的key
vcl_pruge:在收到 purge请求时,执行此函数,清空特定页面/资源的缓存。
vcl_deliver:将在缓存中找到的请求的内容发送给客户端前调用。
vcl_backend_fetch:向后端主机发送请求前,调用。可修改发往后端的请求
vcl_backend_response:获得后端主机的响应后,调用。
vcl_backend_error:当从后端主机获取资源时失败时,调用。
vcl_init:VCL加载时调用此函数,用于初始化varnish模块(类似于awk中的BEGIN)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用。用于清理varnish模块(类似于awk中的END)

内建变量:

varnish_第3张图片

req. :request,表示由客户端发来的请求报文相关;
bereq.
:由varnish发往BE主机的httpd请求相关;
beresp. :由BE主机响应给varnish的响应报文相关;
resp.
:由varnish响应给client相关;
obj. :存储在缓存空间中的缓存对象的属性;只读;
常用变量:
bereq.
, req.*:

bereq.http.HEADERS
bereq.request:请求方法;
bereq.url:请求的url;
bereq.proto:请求的协议版本;
bereq.backend:指明要调用的后端主机;
req.http.Cookie:客户端的请求报文中Cookie首部的值;
req.http.User-Agent ~ "chrome"

beresp., resp.

beresp.http.HEADERS
beresp.status:响应的状态码;
reresp.proto:协议版本;
beresp.backend.name:BE主机的主机名;
beresp.ttl:BE主机响应的内容的余下的可缓存时长;

obj.*

obj.hits:此对象从缓存中命中的次数;
obj.ttl:对象的ttl值

server.*

server.ip varnish主机的ip
server.hostname varnish的主机hostname

client.*

lient.ip 请求客户端的 ip

varnish配置文件

1.varnish.params 配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制;
通常这个配置文件不需要太大的改动。
一般较为常见的改动为

指定监听的服务端口:          
VARNISH_LISTEN_PORT=6081
VARNISH_LISTEN_PORT=80
设置存储类型以及大小;Varnish 4中默认使用malloc(即内存)作为缓存对象存储方式
VARNISH_STORAGE="malloc,256M"
VARNISH_STORAGE="malloc,1024M"
进程池配置,(视生产环境而定)
#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" 
  1. default.vcl 配置各Child/Cache线程的缓存策略; 配置个缓存默认文件
    默认里面为空,这里可根据需求添加
vcl 4.0;
# Default backend definition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
sub vcl_recv {
}
sub vcl_backend_response {
}
sub vcl_deliver {

}
[root@cnetos7 varnish]#varnishadm -S secret -T 127.0.0.1:6082  可查看默认的 default.vcl配置
vcl.show  -v boot  

自己做的配置样本:

vcl 4.0;

import directors;     //加载后端负载均衡模块

probe healthchk {         //后端健康检查
        .url = "/.healthchk.html";    //检测后端是否有.healthchk文件,
        .timeout = 2s;      // 超时时长
        .interval = 2s;     //检测频度
        .window = 8;     //  基于最近的多少次检查来判断其健康状态
        .threshold = 5;   //最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的
}

backend appsrv1 {        //后端服务器 动态1
    .host = "192.168.18.99";
    .port = "80";
    .probe = healthchk;
}
backend appsrv2 {        //后端服务器 动态2
    .host = "192.168.18.100";
    .port = "80";
    .probe = healthchk;
}
backend websrv1 {    //后端服务器 静态1
    .host = "192.168.18.101";
    .port = "80";
    .probe = healthchk;
}
backend websrv2 {    //后端服务器 静态2
    .host = "192.168.18.102";
    .port = "80";
    .probe = healthchk;
}

acl purgers {      //定义允许清理缓存的IP
        "127.0.0.0"/8;
        "192.168.18.131"/32;
}
acl baner {    //定义允许清理同一类的缓存的IP
         "127.0.0.1"/8;
}

sub vcl_init {           //创建后端服务器组
        new websrvs  = directors.round_robin();  //静态组
        websrvs.add_backend(websrv1);
        websrvs.add_backend(websrv2);
        new appsrvs = directors.round_robin(); //动态组
        appsrvs.add_backend(appsrv1);   
}  

sub vcl_recv {
   if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|svg|txt|html|css|js)$") {    // 请求路径中包含 图片,文本,js...格式的转到后端静态服务器组,否则转到动态服务器组
        set req.backend_hint = websrvs.backup();
        }else {
        set req.backend_hint = appsrvs.backup();
   }

    if (req.url ~ "(?i)^/admin") {    //请求路径中含admin的直接不缓存,直接连向后端服务器
        return(pass);
    }

   if (req.method == "PURGE") {  //如果请求方法是PURGE,也就是裁剪缓存
        if (!client.ip ~ purgers) {
                return(synth(405,"Purging not allowed for " + client.ip));  //如果客户端IP不在我们之前定义的ACL for purges中,提示如下信息
        }
        return(purge);
        }

  if (req.method == "BAN") {    //BAN请求的处理
        if (!client.ip ~ baner) {
                return(synth(405,"baning  not allowed for " + client.ip));
        }
        ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
        return (synth(200,"Ban added"));
        }

    if (req.method == "PURGE") {    // PURGE请求的处理
        return(purge);
    }

   if (req.restarts == 0) {        // #记录客户端ip
        if (req.http.X-Fowarded-For) {
           set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
        } else {
           set req.http.X-Forwarded-For = client.ip;
        }
   }

}

sub vcl_purge {   //定义裁剪缓存的提示信息
        return (synth(200,"Purged."));
}

    if ( beresp.status != 200 && beresp.status != 404 ) {    // 如果相应的状态码不是200或者404,则不缓存
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    }
   set beresp.ttl = 1h;   //设置默认ttl缓存为 1小时
   set beresp.grace = 30s;   //意思在30s 内复制旧的请求结果给客户端
    return (deliver);
}

sub vcl_deliver {    // 为响应添加X-Cache首部,显示缓存是否命中
    if (obj.hits > 0) {
        set resp.http.X-Cache = " Hit via " + server.ip;     //提示没有命中
    } else {
        set resp.http.X-Cache = " Miss  via " + server.ip;  // 提示有命中
    }
}

你可能感兴趣的:(varnish)