varnish运行原理及配置

Varnish作为一个HTTP反向代理和缓存加速器,其工作原理是每个线程处理一个用户请求,线程总数由线程池控制,与物理核心数相关。Varnish支持内存和磁盘缓存,并提供了多种缓存存储类型、配置选项、管理工具如varnishadm。此外,还涉及缓存对象的修剪、后端健康检查、日志区域以及内建函数等关键功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写代码片###### varnish 是squid的升级版,主要应用于http得反向代理和http缓存来提供加速功能

1、varnish工作原理是:是每个线程响应一个用户请求的(某个用户请求到来,accept接收这个请求并分配到某个空闲的worker进程进行处理,

(由worker线程读入缓存根据请求的url,如果能够在缓存中查找到,直接把查找的内容直接响应给客户;如果在缓存中查找不到,就负责到后端服务器查找数据,查找到数据后,根据缓存机制,如果能够缓存,就缓存到本地,再响应给客户端。))

2、varnish能够响应多少用户请求呢?取决于打开线程的总数,用什么来控制线程总数呢??

通过线程池的机制来控制打开多个线程,来响应客户端请求。(一般情况是打开线程池的个数,和物理机的核心数是成正比的。
不能超过物理核心数。)

3、varnish缓存方式:(也可以缓存到内存和磁盘)

缓存数据的存储方式:在缓存空间中固定分配大小的空间,如果要缓存一个数据根据缓存数据的大小来缓存到最接
近缓存数据大小的空间。

varnish的程序环境:
        /etc/varnish/varnish.params: 配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制;
        /etc/varnish/default.vcl:配置各Child/Cache线程的缓存策略;
主程序:
            /usr/sbin/varnishd
        CLI interface:
            /usr/bin/varnishadm
        Shared Memory Log交互工具:
            /usr/bin/varnishhist
            /usr/bin/varnishlog
            /usr/bin/varnishncsa
            /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 
                日志持久的服务;        
varnish的缓存存储机制( Storage Types):
        -s [name=]type[,options]

        · malloc[,size]
            内存存储,[,size]用于定义空间大小;重启后所有缓存项失效;
        · file[,path[,size[,granularity]]]
            磁盘文件存储,黑盒;重启后所有缓存项失效;
        · persistent,path,size
            文件存储,黑盒;重启后所有缓存项有效;实验;
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...]: 设定指定的参数为只读状态; 
重载vcl配置文件:
        ~ ]# varnish_reload_vcl
varnishadm
varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT
客户端设置
Client Side:
            vcl_recv, vcl_pass, vcl_hit, vcl_miss, vcl_pipe, vcl_purge, vcl_synth, vcl_deliver

vcl_recv:
                hash:vcl_hash
                pass: vcl_pass 
                pipe: vcl_pipe
                synth: vcl_synth
                purge: vcl_hash --> vcl_purge

vcl_hash:
                lookup:
                    hit: vcl_hit
                    miss: vcl_miss
                    pass, hit_for_pass: vcl_pass
                    purge: vcl_purge

Backend Side:
            vcl_backend_fetch, vcl_backend_response, vcl_backend_error

两个特殊的引擎:
            vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs;
            vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;
配置文件各字段逻辑关系:

varnish

Keywords:
call subroutine, return(action),new,set,unset 
操作符:
==, !=, ~, >, >=, <, <=
逻辑操作符:&&, ||, !
变量赋值:=
举例:obj.hits是内建变量,用于保存某缓存项的从缓存中命中的次数;
            if (obj.hits>0) {
                set resp.http.X-Cache = "HIT via " + server.ip;
            } else {
                set resp.http.X-Cache = "MISS from " + server.ip;
            }
变量类型:
内建变量:
            req.*:request,表示由客户端发来的请求报文相关;
                req.http.*
                    req.http.User-Agent, req.http.Referer, ...
            bereq.*:由varnish发往BE主机的httpd请求相关;
                bereq.http.*
            beresp.*:由BE主机响应给varnish的响应报文相关;
                beresp.http.*
            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.*
                    client.ip:发请求至varnish主机的客户端IP;

用户自定义:
            set 
            unset 

示例1:强制对某类资源的请求不检查缓存:
        vcl_recv {
            if (req.url ~ "(?i)^/(login|admin)") {
                return(pass);
            }
        }
示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长; 定义在vcl_backend_response中;
        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:定义在vcl_recv中;
        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);
                }
                ...
            }

添加此类请求的访问控制法则:
            acl purgers {
                "127.0.0.0"/8;
                "10.1.0.0"/16;
            }

            sub vcl_recv {
                if (req.method == "PURGE") {
                    if (!client.ip ~ purgers) {
                        return(synth(405,"Purging not allowed for " + client.ip));
                    }
                    return(purge);
                }
                ...
            }

Banning:
    (1) varnishadm:
                ban <field> <operator> <arg>

                示例:
                    ban req.url ~ ^/javascripts

    (2) 在配置文件中定义,使用ban()函数;

    示例:
                if (req.method == "BAN") {
                    ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
                    # Throw a synthetic page so the request won't go to the backend.
                    return(synth(200, "Ban added"));
                }   

                ban req.http.host==www.ilinux.io && req.url==/test1.html
 如何设定使用多个后端主机:
        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;
            }   

            ...
        }
Director:
        varnish module; 
            使用前需要导入:
                import directors;

        示例:
            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 {
                # send all traffic to the bar director:
                set req.backend_hint = GROUP_NAME.backend();
            }

基于cookie的session sticky:
            sub vcl_init {
                new h = directors.hash();
                h.add_backend(one, 1);   // backend 'one' with weight '1'
                h.add_backend(two, 1);   // backend 'two' with weight '1'
            }

            sub vcl_recv {
                // pick a backend based on the cookie header of the client
                set req.backend_hint = h.backend(req.http.cookie);
            }               
BE Health Check:
        backend BE_NAME {
            .host =  
            .port = 
            .probe = {
                .url= 
                .timeout= 
                .interval= 
                .window=
                .threshold=
            }
        }

.probe:定义健康状态检测方法;
            .url:检测时要请求的URL,默认为”/"; 
            .request:发出的具体请求;
                .request = 
                    "GET /.healthtest.html HTTP/1.1"
                    "Host: www.magedu.com"
                    "Connection: close"
            .window:基于最近的多少次检查来判断其健康状态; 
            .threshold:最近.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;
            }

手动设定BE主机的状态:
            sick:管理down; 
            healthy:管理up;
            auto:probe auto;

设置后端的主机属性:
        backend BE_NAME {
            ...
            .connect_timeout = 0.5s;
            .first_byte_timeout = 20s;
            .between_bytes_timeout = 5s;
            .max_connections = 50;
        }


varnish的运行时参数:
        线程模型:
            cache-worker
            cache-main
            ban lurker
            acceptor:
            epoll/kqueue:
            ...

线程相关的参数:使用线程池机制管理线程;
            在线程池内部,其每一个请求由一个线程来处理; 其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 idle threshold.  Threads in excess of thread_pool_min, which have been idle for at least this long, will be destroyed.
            thread_pool_add_delay:Wait at least this long after creating a thread.
            thread_pool_destroy_delay:Wait this long after destroying a thread.

Timer相关的参数:
            send_timeout:Send timeout for client connections. If the HTTP response hasn't been transmitted in this many seconds the session is closed.
            timeout_idle:Idle timeout for client connections. 
            timeout_req: Max time to receive clients request headers, measured from first non-white-space character to double CRNL.
            cli_timeout:Timeout for the childs replies to CLI requests from the mgt_param.

设置方式:
                vcl.param 
                param.set

永久有效的方法:
                varnish.params
        DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"
varnish日志区域:
shared memory log 
            计数器
            日志信息

        1、varnishstat - Varnish Cache statistics
            -1
            -1 -f FILED_NAME 
            -l:可用于-f选项指定的字段名称列表;

            MAIN.cache_hit 
            MAIN.cache_miss

            # varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss
                显示指定参数的当前统计数据;
            # varnishstat -l -f MAIN -f MEMPOOL
                列出指定配置段的每个参数的意义;

        2、varnishtop - Varnish log entry ranking
            -1     Instead of a continously updated display, print the statistics once and exit.
            -i taglist,可以同时使用多个-i选项,也可以一个选项跟上多个标签;
            -I <[taglist:]regex>
            -x taglist:排除列表
            -X  <[taglist:]regex>

        3、varnishlog - Display Varnish logs

        4、 varnishncsa - Display Varnish logs in Apache / NCSA combined log format
内建函数:
        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: state engine, vcl 
        varnish 4.0:
            vcl_init 
            vcl_recv
            vcl_hash 
            vcl_hit 
            vcl_pass
            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 {
            ...
        }
        backend BE_NAME {} 
        probe PB_NAME {}
        acl ACL_NAME {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值