varnish

/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
}

/* BODY
=============================================================================*/

body {
font-family: Helvetica, arial, freesans, clean, sans-serif;
font-size: 14px;
line-height: 1.6;
color: #000;
background-color: #fff;
padding: 20px;
max-width: 960px;
margin: 0 auto;
}

body>*:first-child {
margin-top: 0 !important;
}

body>*:last-child {
margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}

p {
color: #006666;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}

h1 {
font-size: 28px;
color: #000;
}

h2 {
font-size: 24px;
border-bottom: 1px solid #ccc;
color:#000;
background-color: #009999;
}

h3 {
font-size: 18px;
color: #000;

}

h4 {
font-size: 16px;
}

h5 {
font-size: 14px;
}

h6 {
color: #777;
font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
color: #007FFF;
}

/* LINKS
=============================================================================*/

a {
color: #4183C4;
text-decoration: none;
}

a:hover {
text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
padding-left: 30px;
}

ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;

}

dl {
padding: 0;
}

dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}

dl dt:first-child {
padding: 0;
}

dl dt>:first-child {
margin-top: 0px;
}

dl dt>:last-child {
margin-bottom: 0px;
}

dl dd {
margin: 0 0 15px;
padding: 0 15px;
}

dl dd>:first-child {
margin-top: 0px;
}

dl dd>:last-child {
margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
font-size: 12px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
margin: 0 0px;
padding: 0px 0px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #13117555;
border-radius: 3px;
}

pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: #5cadad;
}

pre {
background-color: #5cadad;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}

pre code, pre tt {
background-color: #5cadad;
border: none;
}

kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #DDDDDD;
background-image: linear-gradient(#F1F1F1, #DDDDDD);
background-repeat: repeat-x;
border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
border-image: none;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
line-height: 10px;
padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}

blockquote>:first-child {
margin-top: 0px;
}

blockquote>:last-child {
margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #f16522;
padding: 0;
}

/* TABLES
=============================================================================*/

table th {
font-weight: bold;
}

table th, table td {
border: 1px solid #ccc;
padding: 6px 13px;
}

table tr {
border-top: 1px solid #ccc;
background-color: #fff;
}

table tr:nth-child(2n) {
background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
max-width: 100%;
border-color: #5cadad;
border-style:solid;
border-width:1px;
}

.highlight { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
color: #0086b3;
}

.pl-e,.pl-en {
color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
color: #333;
}

.pl-ent {
color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
color: #df5000;
}

.pl-id {
color: #b52a1d;
}

.pl-ii {
background-color: #b52a1d;
color: #f8f8f8;
}

.pl-sr .pl-cce {
color: #63a35c;
font-weight: bold;
}

.pl-ml {
color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
color: #1d3e81;
font-weight: bold;
}

.pl-mq {
color: #008080;
}

.pl-mi {
color: #333;
font-style: italic;
}

.pl-mb {
color: #333;
font-weight: bold;
}

.pl-md,.pl-mdhf {
background-color: #ffecec;
color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
background-color: #eaffea;
color: #55a532;
}

.pl-mdr {
color: #795da3;
font-weight: bold;
}

.pl-mo {
color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}

web cache

  1. 程序的局部性特征

     - 时间局部性:刚刚访问过的数据,在很短的时间内会被再次访问到。
    - 空间局部性:一个数据如果被访问到了,则它周边的数据也可能被访问到。
  2. 设备层级衔接方式

     - 两个设备间衔接不上,加用中间层,如缓存
  3. 什么是缓存命中?

     - 从缓存中找到了需要的数据
  4. 什么是命中率?

     - 命中资源数hit/(命中资源数hit+miss资源数),分两类
    - 页面命中率:基于页面数量进行衡量
    - 字节命中率:基于页面的体积进行衡量
  5. 与缓存相关的首部

     - Expires:定义响应资源的过期时间,绝对时间标记,简单粗暴
    - Cache-Control:请求报文和响应报文缓存控制
    - Etag:资源标签
    - If-None-Match:资源标签是否改变
    - Last-Modified:最后一次修改时间
    - If-Modified-Since:缓存时的时间戳
    - Vary
    - Age
  6. Cache-Control控制项

  7. HTTP Validation条件式请求,检查缓存项和原始服务器资源内容是否一致

     - Last Modified/If-Modified-Since
    - 请求服务器使用If-Modified-since,从此缓存时间戳,与原始服务器上是否匹配,如果改变,直接响应(200)
    - 若没变,last-modified (304),不适用变化频繁的资源
    - Etag/If-None-Match
    - 给同样内容加一个标签Etag,内容改变时Etag标签也会改变,
    - 请求服务器使用If-None-Match向http服务器询问标签是不是不匹配,若匹配则响应not modifyed(304),
    - 否则http服务器直接响应(200)
    - 相对时间和检查机制结合使用
    - 在缓存有效期内从缓存响应,过期后去服务器检查资源是否更新

varnish

  1. 缓存开源解决方案

         - varnish
    - 充分利用epoll机制(能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率),并发量大,单连接资源较轻
    - squid
    - 在较大并发下,稳点性好,老当益壮
  2. 什么是varnish

     - varnish是一个轻量级的Cache和反向代理软件,通常只为httpd提供缓存
  3. varnish架构

     - 主要由核心守护进程varnishd组成
    - Manager Process
    - 管理进程,相当于nginx的主控进程,不处理用户请求
    - Cacher Process
    - 线程Storage:完成缓存存储管理
    - 线程Log/Stats:日志记录----->存入共享内存Shared Memory Log中
    - 线程Worker threads:真正处理用户请求,通过线程池来定义,最大并发(线程池*线程池最大并发)
    - shared memory log
    - varnishlog:读取日志文件,保存在磁盘中
    - varnishstat:读取统计数据,计数器
    - VCL配置接口:varnish配置语言
    - varnishadm:让varnish加载新配置文件
    - VCC Process:varnish的c编译器
  4. 安装(centos 7中varnish被收入epel仓库)

     - [root@ _1_ ~]# yum -y install varnish
  5. 程序环境

     配置文件:
    - /etc/varnish/varnish.params(/etc/sysconfig/varnishd):配置varnish服务进程的工作特性(监听地址和端口,缓存机制等)
    - /etc/varnish/default.vcl:配置各Child/Cache线程的工作特性
    主程序:
    - /usr/sbin/varnishd
    CLI interface:
    - /usr/bin/varnishadmin:通过此管理工具,完成与Manager Process的交互,进而控制varnish的工作特性
    Share Memory Log交互工具:
    - /usr/bin/varnishhist:日志历史
    - /usr/binvarnishlog:记录详细log(请求报文首部,响应报文首部等)
    - /usr/bin/varnishcsa:格式化记录日志
    - /usr/bin/varnishstat:日志统计
    - /usr/bin/varnishtop:日志排序分析
    测试工具程序:
    - /usr/bin/varnishtest
    VCL配置文件重载程序:
    - /usr/sbin/varnish_reload_vcl:此程序会编译配置文件
    Systemd Unit File:
    - /usr/lib/systemd/system/varnish.service:varnish服务
    - /usr/lib/systemd/system/varnishlog.service:原始记录日志(保存磁在盘上)
    - /usr/lib/systemd/system/varnishncsa.service:ncsa格式日志(保存磁在盘上)
  6. varnish的缓存存储机制(Storage Types):

     - malloc[,size]:内存存储,[,size]用于定义空间大小,重启后所有缓存项失效
    - file[,path[,size[,granularity]]]:文件存储,黑盒,重启后所有缓存项失效
    - persistent,path,size:文件存储,黑盒,重启后所有缓存项有效(试验阶段)
  7. varnish的程序选项

     - 程序选项:/etc/varnish/varnish.params文件;
    - -a address[:port][,address[:port][...]:默认为6081端口;
    - -T address[:port]:默认为6082端口;
    - -s [name=]type[,options]:定义缓存存储机制;
    - -u user
    - -g group
    - -f config:VCL配置文件;
    - -F:运行于前台;
    - 运行时参数:/etc/varnish/varnish.params文件, DEAMON_OPTS
    - DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
    - -p param=value:设定运行参数及其值,可重复使用多次
    - -r param[,param...]:设定指定的参数为只读状态
  8. 重载vcl配置文件:

         - ~]# varnish_reload_vcl
  9. varnishadm管理工具

     连接:
    - ~]# varnishadm -S /etc /varnish/secret -T [ADDRESS:]PORT
    配置文件相关:
    - vcl.list:查看所有编译过的配置文件
    - vcl.load <configname> <filename>:装载,加载并编译
    - vcl.use <configname>:激活
    - vcl.discard <configname>:删除配置文件
    运行时参数:
    - param.show -l:显示列表
    - param.show <PARAM> 显示指定PARAM参数
    - param.set <PARAM> <VALUE> 设置PARAM的值 缓存存储:
    - storage.list
    后端服务器:
    - backend.list
  10. 缓存流程图解

    - 一个请求进入,varnish收下这个请求,判断是否对这个请求做处理
    - 访问控制,直接拒绝
    - 请求方法不识别,直接找后端服务器响应
    - 正常请求,进入下一步
    - 查询此请求方法是否能缓存
    - 不能缓存(如post,put),交给vcl_fetcg,由vcl_fetch投递给后端服务器响应
    - 能缓存,进入下一步
    - vcl_hash基于hash查找缓存中是否有对应资源
    - 如果命中,从本地缓存中直接响应给客户端
    - 若未命中,通过vcl_fetch到后端服务器取回资源,然后先缓存,再响应给客户端
  11. VCL状态引擎切换
    - vcl_recv收到请求,查找vcl_hash
    - 若命中(传递值hit),交由vcl_hit
    - hit命中,直接从缓存中响应,交由vcl_deliver投递给客户端
    - vcl_hash -(hit)-> vcl_hit --> vcl_deliver
    - 未命中(传递值miss),交由vcl_miss
    - 交由vcl_backend_fetch请求后端服务器
    - vcl_hash -(miss)-> vcl_miss --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
    - 若要删除缓存项(传递值purge),交由vcl_purge
    - 交由vcl_synh管理缓存,删除对应缓存
    - vcl_hash -(purge)-> vcl_purge --> vcl_synth
    - 若不能理解请求(传递值pipe),交由vcl_pipe,请求被直接送至后端服务器
    - vcl_hash -(pipe)-> vcl_pipe
    - 并发连接超出(传递值busy),进入waiting状态,会等待重新请求查询缓存
    - 传递值(pass,hit-for-pass),交由vcl_pass
    - vcl_hit和vcl_miss也能交由给pass
    - 两个特殊引擎:
    - vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化vMODS
    - vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用,主要用于清理vMODS

VCL语法(4.0)

  1. 语法格式

     - 文件开始要注明vcl版本号:vcl 4.0;
    - //,#,/*,*/为注释
    - 子例行Subroutines使用sub关键字;例如sub_recv {...};
    - 不支持循环,但支持条件语法,支持內建变量(受限于引擎)
    - 使用一个keyword基于return函数终止当前状态引擎,并决定交给哪一个状态引擎
    - “域”专用配置,在一个状态引擎中的配置只对当前状态引擎有效
  2. VCL Finite State MAchine

     - 每一个请求被单独处理
    - 请求和请求间任何时间都是隔离的
    - 各状态引擎有相关性,通过return连接
    - 內建VCL code一直有效,并附加在自建的代码之后(vcl.show -v boot)
  3. 三类主要语法

     - sub subroutine {
    ...
    }
    - if CONDITION {
    ...
    } else {
    ...
    }
    - return(), hash_data()
  4. 內建函数和keyword

     函数:
    regsub(str,regex,sub):字符串为str,根据正则regex模式匹配,把匹配到的内容替换为sub,只替换一次
    regsuball(str,regex,sub):和regsub相同,替换所有
    ban(boolean expression):符合表达式的都清理
    hash_data(input):对input做hash计算
    synthetic:
    Keywords:
    call subrouting:调用子例行程序
    return(action):指明下一个动作
    new:
    set:设定变量的值
    unset:取消变量的值
    布尔型表达式操作符:
    ==,!=,~,>,>=,<,<=
    逻辑操作符:&&,||,!
    变量赋值:=
  5. 例:若通过缓存响应给客户端,在响应首部添加X-Cache,并设置值

     在deliver段中添加条件判断
    sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
    if (obj.hits>0) {
    set resp.http.X-Cache = "HIT via " + server.ip;
    } else {
    set resp.http.X-Cache = "MISS via " + server.ip;
    }
    }
    重新加载配置文件
    [root@ _18_ /etc/varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
    varnish> vcl.load conf1 default.vcl
    200
    VCL compiled. vcl.list
    200
    active 0 boot
    available 0 conf1 vcl.use conf1
    200
    VCL 'conf1' now active varnish> vcl.list
    200
    available 0 boot
    active 0 conf1
  6. 客户端第一次访问,响应码为200,资源由web服务器返回。X-Cache为MISS

  7. 客户端第二次访问,响应码340,资源由缓存服务器返回。X-Cache为HIT

  8. 变量类型


  9. 示例:URL中带有login或admin的字符串不检查缓存

                 sub vcl_recv {
    # Happens before we check if we have this in cache already.
    #
    # Typically you clean up the request here, removing cookies you don't need,
    # rewriting the request, etc.
    if (req.url ~ "(?i)^/(login|admin)") { #(?!)为正则表达式模式标志位,i为不区分大小写
    return(pass);
    }
    }
    第一次访问:X-Cache值为MISS
    Request URL:http://192.168.100.73/admin/
    Request Method:GET
    Status Code:304 Not Modified
    Remote Address:192.168.100.73:80 Age:0
    Connection:keep-alive
    Date:Wed, 02 Nov 2016 02:41:24 GMT
    ETag:"e0102-6-5403f450439af"
    Server:Apache/2.2.15 (CentOS)
    Via:1.1 varnish-v4
    X-Cache:MISS via 192.168.100.73
    X-Varnish:33
    第二次访问,X-Cache的值依然为MISS,varnish并未通过缓存响应
    Request URL:http://192.168.100.73/admin/
    Request Method:GET
    Status Code:304 Not Modified
    Remote Address:192.168.100.73:80
    Response Headers
    view source
    Age:0
    Connection:keep-alive
    Date:Wed, 02 Nov 2016 02:50:04 GMT
    ETag:"e0102-6-5403f450439af"
    Server:Apache/2.2.15 (CentOS)
    Via:1.1 varnish-v4
    X-Cache:MISS via 192.168.100.73
    X-Varnish:32780
  10. 对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长;

    if (beresp.http.cache-control !~ "s-maxage") {
    if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
    unset beresp.http.Set-Cookie;
    set beresp.ttl = 3600s;
    }
    }
  11. 缓存对象的修剪:purge,ban (purge:对某特定资源清理缓存,ban:清理符合条件的缓存)

    执行purge操作:
    sub vcl_purge {
    return (synth(200,"Purged")); #vcl_purge清理缓存,调用synth,合成响应报文 客户端第一次请求
    [root@ _26_ /etc/varnish]# curl -I http://192.168.100.73
    HTTP/1.1 200 OK
    Date: Sat, 12 Nov 2016 10:44:03 GMT
    Server: Apache/2.2.15 (CentOS)
    Last-Modified: Tue, 01 Nov 2016 15:50:24 GMT
    ETag: "e0104-7-5403f48611496"
    Content-Length: 7
    Content-Type: text/html; charset=UTF-8
    X-Varnish: 65552 65548
    Age: 4
    Via: 1.1 varnish-v4
    X-Cache: MISS via 192.168.100.73
    Connection: keep-alive 客户端第二次请求:
    [root@ _23_ /etc/varnish]# curl -I http://192.168.100.73
    HTTP/1.1 200 OK
    Date: Sat, 12 Nov 2016 10:44:03 GMT
    Server: Apache/2.2.15 (CentOS)
    Last-Modified: Tue, 01 Nov 2016 15:50:24 GMT
    ETag: "e0104-7-5403f48611496"
    Content-Length: 7
    Content-Type: text/html; charset=UTF-8
    X-Varnish: 32780 65548
    Age: 1
    Via: 1.1 varnish-v4
    X-Cache: HIT via 192.168.100.73
    Connection: keep-alive 客户端使用PURGE请求:
    [root@ _27_ /etc/varnish]# curl -X PURGE -I http://192.168.100.73
    HTTP/1.1 501 Method Not Implemented
    Date: Sat, 12 Nov 2016 10:54:01 GMT
    Server: Apache/2.2.15 (CentOS)
    Allow: GET,HEAD,POST,OPTIONS,TRACE
    Content-Length: 297
    Connection: close
    Content-Type: text/html; charset=iso-8859-1 客户端再次请求:显示X-Cache为MISS,达到了清理缓存的效果 [root@ _28_ /etc/varnish]# curl -I http://192.168.100.73
    HTTP/1.1 200 OK
    Date: Sat, 12 Nov 2016 10:54:32 GMT
    Server: Apache/2.2.15 (CentOS)
    Last-Modified: Tue, 01 Nov 2016 15:50:24 GMT
    ETag: "e0104-7-5403f48611496"
    Content-Length: 7
    Content-Type: text/html; charset=UTF-8
    X-Varnish: 65554
    Age: 0
    Via: 1.1 varnish-v4
    X-Cache: MISS via 192.168.100.73
    Connection: keep-alive
  12. 何时执行purge操作

    sub vcl_recv {
    if(req.method == "PURGE") {
    return(purge);
    }
    }
  13. 添加purge请求的访问控制法则

        acl purges {
    "127.0.0.0"/8;
    "10.1.0.0"/16;
    } sub vcl_recv {
    if(req.method == "PURGE") {
    if(client.ip ~ purges) {
    return(synth(405,"Purging not allowed for" + client.ip))
    }
    }
    } 其他客户端访问,被拒绝
    [root@ _4_ ~]# curl -X PURGE http://192.168.100.73
    <!DOCTYPE html>
    <html>
    <head>
    <title>405 not allowed purge method for 192.168.100.63</title>
    </head>
    <body>
    <h1>Error 405 not allowed purge method for 192.168.100.63</h1>
    <p>not allowed purge method for 192.168.100.63</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 32820</p>
    <hr>
    <p>Varnish cache server</p>
    </body>
    </html> 本机访问,purge成功:
    [root@ _54_ /etc/varnish]# curl -X PURGE http://127.0.0.1
    <!DOCTYPE html>
    <html>
    <head>
    <title>200 purged</title>
    </head>
    <body>
    <h1>Error 200 purged</h1>
    <p>purged</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 65572</p>
    <hr>
    <p>Varnish cache server</p>
    </body>
    </html>
  1. 设定使用多个后端主机:

    backend default {
    .host = "192.168.100.63";
    .port = "80";
    } backend appsrv {
    .host = "192.168.100.62";
    } sub vcl_recv {
    if (req.url ~ "(?i)\.php$") {
    set req.backend_hint = appsrv;
    } else {
    set req.backend_hint = default;
    }
    } Director:调度
    varnish module;
    使用前需要导入:
    import director; 示例:
    import directors; # load the directors backend server1 {
    .host =
    .port =
    }
    backend server2 {
    .host =
    .port =
    } sub vcl_init {
    new GROUP_NAME = directors.round_robin();
    GROUP_NAME.add_backend(server1);
    GROUP_NAME.add_backend(server2);
    } sub vcl_recv {
    set req.backend_hint = GROUP_NAME.backend();
    }
  1. 健康状态检测

    BE Health Check:
    backend BE_NAME {
    .host =
    .port =
    .probe = {
    .url=
    .timeout=
    .interval=
    .window=
    .threshhold=
    }
    }
    .probe:定义健康状态检测方法;
    .url:检测时请求的URL,默认为”/";
    .request:发出的具体请求;
    .request =
    "GET /.healthtest.html HTTP/1.1"
    "Host: www.magedu.com"
    "Connection: close"
    .window:基于最近的多少次检查来判断其健康状态;
    .threshhold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;
    .interval:检测频度;
    .timeout:超时时长;
    .expected_response:期望的响应码,默认为200; 健康状态检测的配置方式:
    (1) probe PB_NAME = { }
    backend NAME = {
    .probe = PB_NAME;
    ...
    } (2) backend NAME {
    .probe = {
    ...
    }
    } 示例:
    probe check {
    .url = "/.healthcheck.html";
    .window = 5;
    .threshold = 4;
    .interval = 2s;
    .timeout = 1s;
    } backend default {
    .host = "10.1.0.68";
    .port = "80";
    .probe = check;
    } backend appsrv {
    .host = "10.1.0.69";
    .port = "80";
    .probe = check;
    } 使用管理工具设定健康状态:
    backend.set_health appsrv healthy|sick

varnish的参数

  1. 线程相关的参数:

     在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力
    thread_pools:Number of worker thread pools. 线程池数量,最好小于或等于CPU核心数量;
    thread_pool_max:The maximum number of worker threads in each pool.最大并发连接数
    thread_pool_min:The minimum number of worker threads in each pool. 额外意义为“最大空闲线程数
    最大并发连接数=thread_pools * thread_pool_max thread_pool_timeout:线程空闲超时时长,保留为最大空闲进程数
    thread_pool_add_delay:创建线程延时
    thread_pool_destroy_delay:销毁进程延时 设置方式:
    vcl.param
    param.set thread_pool_max 1024 永久有效的方法:
    varnish.params
    DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"
  2. 日志区域

     varnishstat 缓存相关状态日志
    -1 只显示一次,不动态刷新
    -l:显示所有字段名
    -f:指定字段名
    例:varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss varnishtop 缓存实时日志排序显示
    -1
    -i taglist标签
    -I <[taglist:]regex> 可以同时使用多个-i选项,也可以一个选项跟上多个标签
    -x taglist:排除列表
    -X <[taglist:]regex> varnishlog 实时详细josn格式日志
    varnishncsa 实时常规日志输出
  3. 内建函数

     hash_data():指明哈希计算的数据;减少差异,以提升命中率;
    regsub(str,regex,sub):把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewrite
    regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替换为sub;
    return():
    ban(expression)
    ban_url(regex):Bans所有的其URL可以被此处的regex匹配到的缓存对象;
    synth(status,"STRING"):purge操作;

总结

    varnish 4.0:子例程
vcl_init 定义服务器组,初始化
vcl_recv 接收和处理请求,当请求到达并成功接收后被调用,判断请求数据决定如何处理
vcl_hash hash用户请求,判断是否查缓存,(早期先判断,是否查缓存,再hash)
vcl_hit 缓存命中,在执行lookup指令后,在缓存中找到的请求内容将自动调用该函数
vcl_pass 在此状态下,会直接进入后端请求,即进入fetch(vcl_fetch)状态
vcl_miss 缓存中没有找到请求内容时调用此函数,判断是否需要从后端服务器获取内容
vcl_pipe 不理解请求,将请求直接传递后端主机,并将后端响应原样返回客户端
vcl_waiting 操作忙,送至此
vcl_purge 清理缓存
vcl_deliver 投递给客户端
vcl_synth 合成响应报文
vcl_fini 清理清理定义内容 vcl_backend_fetch 对请求进行后端获取,发送请求,获得数据,根据设置进行本地存
vcl_backend_response 获得后端主机的响应后,可调用此函数
vcl_backend_error 从后端主机获取源文件失败时,调用此函数 sub VCL_STATE_ENGINE 定义状态引擎(4.0级以后 默认状态附加在配置之后)
backend BE_NAME {} 定义后端主机
probe PB_NAME {} 定义健康状态监测
acl ACL_NAME {} 定义访问控制

varnish的更多相关文章

  1. 利用varnish做Discuz论坛的缓存服务器

    实验背景:公司有一台BBS服务器,用的是LNMP的架构搭建的.正好手头有一台空闲的虚拟机,于是想着给BBS前端加一台缓存服务器.于是选定了varnish,搜了很多教程,跌跌撞撞的完成了配置.这其中很多 ...

  2. varnish 隐藏版本号

    varnish 隐藏方法: 修改default.vcl配置文件. 找到或添加 vcl_deliver 子程序,代码如下: 1 2 3 4 5 sub vcl_deliver {        unse ...

  3. [转]在windows环境中使用varnish

    varnish 的windows 版本下载地址: http://sourceforge.net/projects/cygvarnish/files/windows-zip-bundle/ 启动:var ...

  4. Varnish常用相关命令工具

    varnishd启动./varnishd  -f /usr/local/varnish-3.0.2/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1: ...

  5. Varnish介绍

    “Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前 ...

  6. varnish 内置函数详细说明

    Subroutine列表 •vcl_recv 在请求开始时候被调用,在请求已经被接收到并且解析后调用.目的就是决定是否处理这个请求,怎么处理,使用哪个后端.vcl_recv以return结束,参数可以 ...

  7. varnish 4.0.3 域名访问的小问题

    1,若端口不是80 端口则匹配的时候必须加端口 if (req.http.host ~ "(?i)^var.test.aa:6081$") {set req.http.host = ...

  8. Varnish简介

    Varnish介绍: Varnish是一个反向HTTP代理,有时也被称为HTTP的加速器或网络加速器:它存在于真实服务器的前面(可能有多级代理),将来自于客户端的请求中的部分内容存储在自身的内存中,以 ...

  9. 学习varnish随笔

    Varnish是一款高性能.开源的反向代理服务器和缓存服务器.Varnish使用内存缓存文件来减少响应时间和网络带宽消耗.这个项目是由挪威的一家报纸Verdens Gang的网络分支起始的,其架构设计 ...

随机推荐

  1. js工厂方式和构造函数

    工厂方式 //工厂方式 : 封装函数 function createPerson(name){ //1.原料 var obj = new Object(); //2.加工 obj.name = nam ...

  2. 两种open()函数

    C语言中文件操作函数中,open()有两种形式: 一种形式是有两个参数open2: 另一种形式是有三个参数open3: 共有的参数有两个,第一个是"被打开文件的路径",第二个是&q ...

  3. jdk1.7和jdk1.8的String的getByte方法的差异

    最近遇到一个奇葩的bug,jdk1.7下正常的程序到了jdk1.8下就不能用了,经过查找原因发现是因为jdk版本升级导致的获取的getbyte时得到的byte数组不同造成的.

  4. Visual Studio 15 Preview 4安装

    今天看到了有Visual Studio 15 Preview 4的安装文件放出,便想去安装体验一下C# 7.0的新语法.谁知安装时遇到一个错误: 手动下载这个补丁安装后,还是提示这个错误.本来以为是还 ...

  5. 重走java--Step 2

    java基础语法(一) 1.java基本数据类型 byte:1个字节,8bit有符号数据类型boolean:2个字节,16bit布尔数值char:2个字节,16bit的Unicode字符类型int:4 ...

  6. MFC控件的SubclassDlgItem

    MFC控件的SubclassDlgItem 要在程序中创建新设计的控件,显然不能用自动创建的办法,因为对话框模板对新控件的特性一无所知.程序可以用手工方法创建控件,在调用派生类的Create函数时,派 ...

  7. vc++ 程序开机自启动和取消启动

    //开机启动 int CMainWnd::CreateRun() { //添加以下代码 HKEY hKey; }; //得到程序自身的全路径 DWORD dwRet = GetModuleFileNa ...

  8. html 报表导出excel防止数字变科学计数

    在html 标签加:  <html xmlns:x="urn:schemas-microsoft-com:office:excel">    在要导出的tr加:  &l ...

  9. HRS(CRLF Injection)

    [HRS(CRLF Injection)] CRLF是”回车 + 换行”(\r\n)的简称.在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CR ...

  10. sql查询当天,一周,一个月数据的语句

    --查询当天:  select * from info where DateDiff(dd,datetime,getdate())=0 --查询24小时内的: select * from info w ...