varnish缓存代理介绍

官方网址:各版本之间差距较大,其中第四版本被epel源收录

概括:

对于网站而言,缓存为王;缓存是对网站加速必不可少的工具;varnish缓存对web来讲,首先是一个http的反向代理服务器;这个反向代理能识别http请求,比方url,然后从本地内存或磁盘取出相应的数据响应给前端负载均衡服务器,然后给客户端。算法常见轮询和随机调度,也不需要和后端服务器有保持会话的关系;如果本地没有缓存数据,再去后端服务器上拿过来放在本地;
有些数据是不能被缓存的,例如数据太大,用户的隐私数据(可能会被其他用户“命中”),所以一般响应数据中带有cookie,attestation(认证)首部的都不予缓存;
varnish一般都是代理后端静态内容,不会涉及到会话或其他用户信息的内容,通常用来做图片存储的前端缓存;为了防止缓存长期在内存中造成内存碎片,一般缓存数据都应该存放在磁盘上,磁盘也应该尽量是SSD类型;
缓存服务器上线前都需要一个“预热”过程。可以使用tcpcopy工具压测,模拟线上的用户访问流量;
squid --> varnish关系就像apache>nginx,老当益壮VS青年新秀;squid高压下稳定要好;varnish更轻量;

流程图:

varnish缓存代理介绍_第1张图片
4.1版本流程图
varnish缓存代理介绍_第2张图片

程序环境

  • /etc/varnish/varnish.params: 配置varnish守护进程的工作特性,例如监听的地址和端口,缓存机制,多少个worker线程;
  • /etc/varnish/default.vcl:配置缓存的工作机制;
  • /usr/sbin/varnishd 主程序
  • /usr/bin/varnishadm 管理接口
  • Shared Memory Log交互工具:
    • /usr/bin/varnishhist
    • /usr/bin/varnishlog
    • /usr/bin/varnishncsa
    • /usr/bin/varnishstat
    • /usr/bin/varnishtop
  • /usr/bin/varnishtest 测试工具程序
  • /usr/sbin/varnish_reload_vcl 配置文件重载程序(完成对varnish配置文件更改后的重载(不要轻易重启服务,重启会造成缓存的数据丢失))
  • 日志持久的服务:
    • /usr/lib/systemd/system/varnishlog.service
    • /usr/lib/systemd/system/varnishncsa.service

varnish缓存的存储机制:

  • varnish -s [name] =type[,options]
    • malloc[,size]
      内存存储;[,size]用于定义空间大小;重启后所有缓存项失效;
    • file[,path[,size]]
      文件存储,黑盒;重启后所有缓存项失效;
    • persistent,path,size
      文件存储,黑盒;重启后所有缓存项有效;但是实验阶段;
      所以,内存空间够就用内存,不够就用磁盘.

程序的运行具有局部性特征:

时间局部性:一个数据被访问过之后,可能很快会被再次访问
空间局部性:一个数据被访问时,其周边的数据也有可能被访问到

安装:

  • yum -y install varnish (注意配置好yum的epel仓库)

内建变量:

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

示例:对后端资源命中是"HIT",未命中是"MISS"

sub vcl_deliver {
                if (obj.hits>0) {
                    set resp.http.X-Cache = "HIT via " + server.ip;
                } else {
                    set resp.http.X-Cache = "MISS via " + server.ip;
                }

示例1:强制对某类资源的请求不检查缓存:

vcl_recv {
     if (req.url ~ "(?i)^/(login|admin)") {
        return(pass);
    }
}

示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长,而不是由后台RS设定的缓存时长:

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;
    }
}

示例3:varnish主动向后端发送客户端的IP(需要配置后台web的配置文件中日志格式):

if (req.restarts == 0) {
    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;
    }
}   

缓存对象的修剪:purge, ban:

            (1) 能执行purge操作
                sub vcl_purge {
                    return (synth(200,"Purged"));
                }
                
            (2) 何时执行purge操作
                sub vcl_recv 
                    if (req.method == "PURGE") {
                        return(purge);
                    }

如何设定使用多个后端主机:

            backend default {
                .host = "172.16.100.6";
                .port = "80";
            }

            backend appsrv {
                .host = "172.16.100.7";
                .port = "80";
            }
            
            sub vcl_recv {              
                if (req.url ~ "(?i)\.php$") {
                    set req.backend_hint = appsrv;
                } else {
                    set req.backend_hint = default;
                }   
                
                ...
            }

如何设定varnish的调度器:

使用前需要导入:
                    import directors;

backend default {
    .host = "172.18.251.137";
    .port = "80";
}

backend image {
    .host = "172.18.254.82";
    .port = "80";
}

sub vcl_init {
        new GROUP_NAME = directors.round_robin();
        GROUP_NAME.add_backend(default);
        GROUP_NAME.add_backend(image);
        }

sub vcl_recv {
         if (req.url ~ "(?i)\.jpg|jpeg$") {
                   set req.backend_hint = image;
         } else {
                   set req.backend_hint = GROUP_NAME.backend();
                }
               }

对后端RS定义健康状态检测方法(七层检测):

.url:检测时请求的URL,默认为”/"
.request:发出的具体请求
.window:基于最近的多少次检查来判断其健康状态
.threshhold:最近.window中定义的有几次是成功的
.interval:检测频度
.timeout:超时时长  .expected_response:期望的响应码,默认为200
.max_connections :最大连接数
示例:
probe check {
         .url = "/index.html";
         .window = 5;
         .threshold = 4;
         .interval = 2s;
         timeout = 1s;
             }

backend default {
    .host = "172.18.251.137";
    .port = "80";
    .probe = check;
}

backend image {
    .host = "172.18.254.82";
    .port = "80";
    .probe = check;
}

删除后端RS响应报文的特定首部:

sub vcl_backend_response {
unset beresp.http.Server;
unset beresp.http.X-Powered-By;
                         }

线程相关的参数:

  • 在线程池内部,其每一个请求由一个线程来处理;
  • 其worker线程的最大数决定了varnish的并发响应能力;
thread_pools:最好小于或等于CPU核心数量(一个线程池相当于cpu的一个核心)
thread_pool_max:每线程池的最大线程数
thread_pool_min:额外意义为“最大空闲线程数”
最大并发连接数=thread_pools乘thread_pool_max
thread_pool_timeout:线程池内的空闲线程超时时长
thread_pool_add_delay:创建第二个空闲线程与第一个线程之间的间隔时长
thread_pool_destroy_delay:杀掉线程时之间的间隔时长
  • 设置方式:
    varnishadm:param.set thread_pools 4 线程池数量为4
  • 永久有效的方法:
    vim varnish.params: DAEMON_OPTS="-p thread_pools=4 -p thread_pool_min=10" 线程池数量为4,线程池内空闲的最少并发连接数为10;随后重启varnish

你可能感兴趣的:(varnish缓存代理介绍)