• 缓存varnish的管理及配置详解


    一 工作原理

    在当前主流的Web服务架构体系中,Cache担任着越来越重要的作用。常见的基于浏览器的C/S架构,Web Cache更是节约服务器资源的关键。而最近几年由FreeBSD创始人之一Kamp开发的varnish更是一个不可多得的Web Cache Server。严格意义上说,Varnish是一个高性能的反向代理软件,只不过与其出色的缓存功能相比,企业更愿意使用其搭建缓存服务器。同时,由于其工作在Web Server的前端,有一部分企业已经在生产环境中使用其作为旧版本的squid的替代方案,以在相同的服务器成本下提供更好的缓存效果,Varnish更是作为CDN缓存服务器的可选服务之一。

    Varnish主要有以下几点特性:
     1.缓存位置:可以使用内存也可以使用磁盘。如果要使用磁盘的话推荐SSD做RAID1
     2.日志存储:日志也存储在内存中。存储策略:固定大小,循环使用
     3.支持虚拟内存的使用。
     4.有精确的时间管理机制,即缓存的时间属性控制。
     5.状态引擎架构:在不同的引擎上完成对不同的缓存和代理数据进行处理。可以通过特定的配置语言设计不同的控制语句,以决定数据在不同位置以不同方式缓存。类似于netfilter中的钩子,在特定的地方对经过的报文进行特定规则的处理。
     6.缓存管理:以二叉堆格式管理缓存数据,做到数据的及时清理。


    二 基本架构

    1. 状态引擎

    2.内部处理流程

    三 配置详解

    1. 简单安装

    [root@node1 ~]# yum install varnish -y
    

    2. 配置详解

    [root@node1 ~]# cd /etc/varnish
    


    配置default.vcl配置文件

    [root@node1 varnish]# cat default.vcl
    # 使用varnish版本4的格式.
    vcl 4.0;
    # 加载后端轮询模块
    import directors;
    #######################健康检查策略区域###########################
    # 名为www_probe的健康检查策略
    probe www_probe {
     .request =
     "GET /html/test.html HTTP/1.1"    # 健康检查url为/html/test.html 协议为http1.1
    # "Host: www.xiaxiaodie.com"        # 访问的域名为www.xiaxiaodie.com
     "Connection: close";        # 检查完关闭连接
    #其他参数 如 超时时间 检查间隔 等 均使用默认
    }
    ##################################################################
    #######################配置后端区域################################
    backend backend_15 {
     .host = "172.18.67.15";
     .port = "80";
     .probe = www_probe; # 使用名为www_probe的健康检查策略
    }
    backend backend_16 {
     .host = "172.18.67.16" 
     .port = "80";
     .probe = www_probe; # 使用名为www_probe的健康检查策略
    }
    #默认后端
    backend default {
     .host = "172.18.67.15" 
     .port = "80";
    }
    ###################################################################
    # 配置后端集群事件
    sub vcl_init {
    # 后端集群有4种模式 random, round-robin, fallback, hash
     # random 随机
     # round-robin 轮询
     # fallback 后备
     # hash 固定后端 根据url(req.http.url) 或 用户cookie(req.http.cookie) 或 用户session(req.http.sticky)(这个还有其他要配合)
     # 把backend_15 和 backend_16配置为轮询集群 取名为www_round_robin
     new www_round_robin = directors.round_robin();
     www_round_robin.add_backend(backend_15);
     www_round_robin.add_backend(backend_16);
     # 把backend_15 和 backend_16配置为随机选择集群 取名为www_random
     new www_random = directors.random();
     www_random.add_backend(backend_15,10);  # 设置backend_15后端的权重为10
     www_random.add_backend(backend_16,5);   # 设置backend_16后端的权重为5
     # 把backend_15 和 backend_16配置为固定后端集群 取名为www_hash 在recv调用时还需要添加东西 看recv例子
     new www_hash = directors.hash();
     www_hash.add_backend(backend_15,1);        # 设置backend_15后端的权重为1
     www_hash.add_backend(backend_16,1);        # 设置backend_16后端的权重为1
    }
    #定义允许清理缓存的IP
    acl purge {
    # For now, I'll only allow purges coming from localhost
     "127.0.0.1";
     "localhost";
    }
    # 请求入口 这里一般用作路由处理 判断是否读取缓存 和 指定该请求使用哪个后端
    sub vcl_recv {
     # 域名为 www.xiaxiaodie.com 的请求 指定使用名为www_round_robin的后端集群  在集群名后加上 .backend() 如只使用单独后端 直接写后端名字即可 如 = backend_16;
     if (req.http.host ~ "node2") {
      set req.backend_hint = www_round_robin.backend();
     }
     # 使用固定后端集群例子 使用名为www_hash的集群
     if (req.http.host ~ "3g.xiaxiaodie.com") {
     set req.backend_hint = www_hash.backend(req.http.cookie);  # 根据用户的cookie来分配固定后端 可以指定其他分配规则
     }
     # 其他将使用default默认后端
     # 把真实客户端IP传递给后端服务器 后端服务器日志使用X-Forwarded-For来接收
     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.method == "PURGE") {
      # 如果发起请求的客户端IP 不是在acl purge里面定义的 就拒绝
      if (!client.ip ~ purge) {
       return (synth(405, "This IP is not allowed to send PURGE requests."));
      }
      # 是的话就执行清理
      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") {
       /* Non-RFC2616 or CONNECT which is weird. */
      return (pipe);
      }
     # 如果不是GET和HEAD就跳到pass 再确定是缓存还是穿透
     if (req.method != "GET" && req.method != "HEAD") {
      return (pass);
     }
     # 缓存通过上面所有判断的请求 (只剩下GET和HEAD了)
     return (hash);
    }
    # pass事件
    sub vcl_pass {
    # 有fetch,synth or restart 3种模式. fetch模式下 全部都不会缓存
    return (fetch);
    }
    # hash事件(缓存事件)
    sub vcl_hash {
    # 根据以下特征来判断请求的唯一性 并根据此特征来缓存请求的内容 特征为&关系
     # 1. 请求的url
     # 2. 请求的servername 如没有 就记录请求的服务器IP地址
     # 3. 请求的cookie
     hash_data(req.url);
     if (req.http.host) {
     hash_data(req.http.host);
     } else {
     hash_data(server.ip);
     }
     # 返回lookup , lookup不是一个事件(就是 并非指跳去sub vcl_lookup) 他是一个操作 他会检查有没有缓存 如没有 就会创建缓存
     return (lookup);
    }
    # 缓存命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
    sub vcl_hit {
     # 可以在这里添加判断事件(if) 可以返回 deliver restart synth 3个事件
     # deliver  表示把缓存内容直接返回给用户
     # restart  重新启动请求 不建议使用 超过重试次数会报错
     # synth    返回状态码 和原因 语法:return(synth(status code,reason))
     # 这里没有判断 所有缓存命中直接返回给用户
     return (deliver);
    }
    # 缓存不命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
    sub vcl_miss {
     # 此事件中 会默认给http请求加一个 X-Varnish 的header头 提示: nginx可以根据此header来判断是否来自varnish的请求(就不用起2个端口了)
     # 要取消此header头 只需要在这里添加 unset bereq.http.x-varnish; 即可
     # 这里所有不命中的缓存都去后端拿 没有其他操作 fetch表示从后端服务器拿取请求内容
     return (fetch);
    }
    # 返回给用户的前一个事件 通常用于添加或删除header头
    sub vcl_deliver {
     # 例子
     # set resp.http.*    用来添加header头 如 set resp.http.xiaxiaodie = "haha"; unset为删除
     # set resp.status     用来设置返回状态 如 set resp.status = 404;
     # obj.hits        会返回缓存命中次数 用于判断或赋值给header头
     # req.restarts    会返回该请求经历restart事件次数 用户判断或赋值给header头
     # 根据判断缓存时间来设置xiaxiaodie-Cache header头
     if (obj.hits > 0) {
      set resp.http.xiaxiaodie_Cache = "cached";
     } else {
     set resp.http.xiaxiaodie_Cache = "uncached";
     }
     #取消显示php框架版本的header头
     unset resp.http.X-Powered-By;
     #取消显示nginx版本、Via(来自varnish)等header头 为了安全
     unset resp.http.Server;
     unset resp.http.X-Drupal-Cache;
     unset resp.http.Via;
     unset resp.http.Link;
     unset resp.http.X-Varnish;
     #显示请求经历restarts事件的次数
     set resp.http.xiaxiaodie_restarts_count = req.restarts;
     #显示该资源缓存的时间 单位秒
     set resp.http.xiaxiaodie_Age = resp.http.Age;
     #显示该资源命中的次数
     set resp.http.xiaxiaodie_hit_count = obj.hits;
     #取消显示Age 为了不和CDN冲突
     unset resp.http.Age;
     #返回给用户
     return (deliver);
    }
    #处理对后端返回结果的事件(设置缓存、移除cookie信息、设置header头等) 在fetch事件后自动调用
    sub vcl_backend_response {
     #后端返回如下错误状态码 则不缓存
     if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) {
      set beresp.uncacheable = true;
     }
     #如请求php或jsp 则不缓存
     if (bereq.url ~ ".(php|jsp)(?|$)") {
      set beresp.uncacheable = true;
     #php和jsp以外的请求
     } else {
     #如请求html 则缓存5分钟
      if (bereq.url ~ ".html(?|$)") {
       set beresp.ttl = 300s;
       unset beresp.http.Set-Cookie;
      #其他缓存1小时 如css js等
      }else{
      set beresp.ttl = 1h;
      unset beresp.http.Set-Cookie;
      }
     }
     #开启grace模式 表示当后端全挂掉后 即使缓存资源已过期(超过缓存时间) 也会把该资源返回给用户 资源最大有效时间为6小时
     set beresp.grace = 6h;
     #返回给用户
     return (deliver);
    }
    

    配置varnish.params配置文件

    [root@node1 varnish]# vim varnish.params
    # Varnish environment configuration description. This was derived from
    # the old style sysconfig/defaults settings
    # Set this to 1 to make systemd reload try to switch VCL without restart.
    RELOAD_VCL=1
    # Main configuration file. You probably want to change it.
    VARNISH_VCL_CONF=/etc/varnish/default.vcl
    # Default address and port to bind to. Blank address means all IPv4
    # and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted
    # quad, or an IPv6 address in brackets.
    # VARNISH_LISTEN_ADDRESS=192.168.1.5
    VARNISH_LISTEN_PORT=80
    # Admin interface listen address and port
    VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
    VARNISH_ADMIN_LISTEN_PORT=6082
    # Shared secret file for admin interface
    VARNISH_SECRET_FILE=/etc/varnish/secret
    # Backend storage specification, see Storage Types in the varnishd(5)
    # man page for details.
    VARNISH_STORAGE="malloc,256M"
    # User and group for the varnishd worker processes
    VARNISH_USER=varnish
    VARNISH_GROUP=varnish
    # Other options, see the man page varnishd(1)
    #DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
    

    3.简单管理工具

    [root@node1 varnish]# varnishadm -S secret -T 127.0.0.1:6082
    200        
    -----------------------------
    Varnish Cache CLI 1.0
    -----------------------------
    Linux,3.10.0-327.el7.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
    varnish-4.0.4 revision 386f712
    Type 'help' for command list.
    Type 'quit' to close CLI session.
    help
    200        
    help [<command>]
    ping [<timestamp>]
    auth <response>
    quit
    banner
    status
    start
    stop
    vcl.load <configname> <filename>
    vcl.inline <configname> <quoted_VCLstring>
    vcl.use <configname>
    vcl.discard <configname>
    vcl.list
    param.show [-l] [<param>]
    param.set <param> <value>
    panic.show
    panic.clear
    storage.list
    vcl.show [-v] <configname>
    backend.list [<backend_expression>]
    backend.set_health <backend_expression> <state>
    ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
    ban.list
    

    四 访问测试

    [root@node1 varnish]# systemctl start varnish.service
    

  • 相关阅读:
    Log4Net记录到MySql
    创建快照
    grep的用法(CentOS7)及有关正则表达式的使用
    samba
    mkdir
    raid0和raid5的 实验过程
    route
    source和sh执行脚本时的差异
    echo命令的简单用法和实例
    smbpasswd和pdbedit
  • 原文地址:https://www.cnblogs.com/iuskye/p/6885423.html
Copyright © 2020-2023  润新知