设为首页 收藏本站
云服务器等爆品抢先购,低至4.2元/月
查看: 2157|回复: 0

[经验分享] varnish的了解与常用配置使用

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-8-18 08:57:37 | 显示全部楼层 |阅读模式
Varnish是一款高性能的开源HTTP加速器及反向代理服务器。

varnish架构图:


wKioL1mVUDejtnnAAAGEvDyp-uQ564.png

    Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。

    接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。

    分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。

    释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。

    整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。


配置使用varnish

CentOS7上epel源上直接安装使用:varnish-4.0.5

[iyunv@node3 dylan]# yum install varnish                epel源

[iyunv@node3 dylan]# cd /etc/varnish/

[iyunv@node3 varnish]# cp varnish.params{,.bak}

[iyunv@node3 varnish]# systemctl start varnish.service

示例:

一台web服务器安装httpd作为后端服务器

[iyunv@localhost ~]# vim /var/www/html/index.html

<h1> Backend Server 1</h1>

varnish主机上编辑:

[iyunv@node3 varnish]# vim default.vcl

backend default {

    .host = "192.168.0.150";                    ###后端服务器地址            

    .port = "80";                ###端口

[iyunv@node3 varnish]# systemctl reload varnish.service


举几个常用示例:

1、.测试缓存命中情况:

[iyunv@node3 ~]# vim /etc/varnish/default.vcl

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

    }   else {

        set resp.http.X-Cache = "Miss";

    }

}

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;

    }

}


###使varnishadm工具来管理

[iyunv@node3 ]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082    ###varnishadm命令

vcl.load test1 default.vcl

200        

VCL compiled.

varnish> vcl.use test1

200        

VCL 'test1' now active


2、缓存对象修剪

acl purgers {                    ###添加访问控制        varnish4.0                                    

        "127.0.0.0"/8;

        "192.168.0.0"/16;

}


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 ~"^/test.html$") {

                return(pass);

        }

        if (req.method == "PURGE"){

                if (!client.ip ~ purgers){        ###ip不属于定义端内的返回405错误

                        return(synth(405,"Purging not allow for" + client.ip));

                }

        return(purge);

        }

}


sub vcl_purge {

        return(synth(200,"Purged,"));                ###修剪

}

管理端:

varnish> vcl.load test9 default.vcl                     ###重新配置

200        

VCL compiled.

vcl.use test9                                ###使用新配置

200        

VCL 'test9' now active



3、###设定多个后端主机

backend default {

    .host = "192.168.0.150";

    .port = "80";

}

backend appsrv {                ###定义一个后端主机

    .host = "192.168.0.113";

    .port = "80";

}

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)\.php$") {

        set req.backend_hint = appsrv;

    }  else {

        set req.backend_hint = default;

    }

}

vcl.load test10 default.vcl

200        

VCL compiled.

vcl.load

varnish> vcl.use test10

200        

VCL 'test10' now active



4、设定负载均衡效果:

Directors:

import directors;                ###首先import

backend websrv1 {                ###定义两个后端主机

    .host = "192.168.0.150";

    .port = "80";

}

backend websrv2 {

    .host = "192.168.0.115";

    .port = "80";

}

    sub vcl_init {

        new websrvs = directors.round_robin();

        websrvs.add_backend(websrv1);

        websrvs.add_backend(websrv2);

}

sub vcl_recv {

  set req.backend_hint = websrvs.backend();

}


管理端使用:

varnish> vcl.load test13 default.vcl

200        

VCL compiled.

vcl.use test13

200        

VCL 'test13' now active



5、健康状态检测:

    backend websrv1 {

        .host = "192.168.0.115";

        .host = "80";

        .prode = {

            .url = "/";

            .interval = 1s;

            .window = 8;

            .threshold = 5;

            .timeout = 2s;

            }

        }

            .request =

                "GET /HTTP/1.1"

                "Host: 192.168.0.115"

                "connection:Close"

            .expected_response=200;


完整性示例:

vcl 4.0;

import directors;

# Default backend definition. Set this to point to your content server.

backend websrv1 {

    .host = "192.168.0.150";

    .port = "80";

    .probe = {

    .url = "/";

    .interval = 2s;

    .window = 5;

    .threshold = 4;

     }

}

backend websrv2 {

    .host = "192.168.0.115";

    .port = "80";

    .probe = {

    .url = "/";

    .interval = 2s;

    .window = 5;

    .threshold = 4;

     }

}

sub vcl_init {

    new websrvs = directors.round_robin();

    websrvs.add_backend(websrv1);

    websrvs.add_backend(websrv2);

}


sub vcl_recv {

   

#    if (req.url ~"(?i)\.php$") {

#    set req.backend_hint = appsrv;

#    }  else {

    set req.backend_hint = websrvs.backend();

#    }

    if (req.url ~"^/login") {

        return(pass);

    }

    if (req.method == "PURGE"){

        if (!client.ip ~ purgers){

            return(synth(405,"Purging not allow for" + client.ip));

        }   

    return(purge);

    }         

}


sub vcl_purge {

    return(synth(200,"Purged,"));

}

acl purgers {

    "127.0.0.0"/8;

    "192.168.0.0"/16;

}


sub vcl_backend_response {

   

    if (beresp.http.cache-control !~ "s-masage") {

    if (bereq.url ~ "(?i)\.jpg$") {

    set beresp.ttl = 7200s;

    unset beresp.http.Set-Cookie;

    }

    if (bereq.url ~ "(?i)\.css$"){

    set beresp.ttl = 3600s;

    unset beresp.http.Set-Cookie;

    }

    }

}


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;

    }

#    if (beresp.backend.name ~  "appsrv") {

#    set resp.htttp.X-Server = "appsrv";

#   }

}




varnish几个常用的命令工具:

    varnishadm

    varnishtop   

        varish log entry ranking

    varnishlog

        varnishlog.service

    varnishncsa

        varnishncsa.service

    varnishstat

        Varnish Cache statistics


varnish的运行时参数:                                配置文件中修改全局生效

[iyunv@node3 ~]# vim /etc/varnish/varnish.params

DAEMON_OPTS="-p thread_pools=4"                        ###设置线程池为4

[iyunv@node3 ~]# systemctl restart varnish.service    ###不能随便重启,否则缓存全部失效

[iyunv@node3 varnish]# varnishstat             ###查看状态


附:

变量   

    內键变量:

        req.*:由客户端发来的http请求相关

            req.http.*:请求报文各首部

        bereq.*:由varnish向backend主机发出的http请求

            bere.http.*

        beresp.*:由backend主机发来的http响应报文

        resp.*: 由varnish响应给client的http响应报文

            resp.http.*:响应报文各首部

        obj.*:存储在缓存空间的缓存对象属性,只读


        client.*,server.*,storage.*:可用在所有的client side 的sub riutines中

            

        

            自定义: set

        

    常用的变量:

        bereq:

            bereq.http.HEADERS

            bereq.request:请求方法

            bereq.url:请求的url

            bereq.proto:协议版本

            bereq.backend:指明要调用的后端主机

        

        beresp:

            beresp.proto

            beresp.status:响应的状态码

            beresp.reason

            beresp.backend.name

            baresp.http.HEADERA:

            beresp.ttl:后端服务器响应中的内容余下的生存时长

               

        obj:

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

            obj.ttl:对象的ttl值

               

        server:

            server.ip

            server.hostname

               

        req.method:请求方法

        req.url:请求的url





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-403069-1-1.html 上篇帖子: 可靠、高性能的 TCP/HTTP 负载均衡器 下篇帖子: HAProxy反代基本配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表