varnish

varnish:

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



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

HTTP请求处理基本流程:
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)

内建变量:


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;  // 提示有命中
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 228,702评论 6 534
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,615评论 3 419
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 176,606评论 0 376
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,044评论 1 314
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,826评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,227评论 1 324
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,307评论 3 442
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,447评论 0 289
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,992评论 1 335
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,807评论 3 355
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,001评论 1 370
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,550评论 5 361
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,243评论 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,667评论 0 26
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,930评论 1 287
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,709评论 3 393
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,996评论 2 374

推荐阅读更多精彩内容