34.0varnish

varnish
这里写图片描述

结构化数据:按照一定的模式scheme存放数据,如mariadb上的表结构
半结构化数据:数据自带元数据,无固定scheme约束的数据,
非结构化数据:如日志,数据无表头,无元数据
结构化数据:关系型数据库存放,可以分布式存储
半结构化数据:各种各样的nosql存放,可以分布式存储
非结构化数据:文件系统接口存放,可以分布式文件系统存储,若不是文件系统存放,则是分布式块存储

WebPage Cache

缓存按照工作方式划分:
  代理式缓存(proxied),如nginx的缓存功能,varnish作为专门缓存
  旁路式缓存(bypass),如memcached,临时缓存,客户端访问mysql,把数据请求下来,并自行决定是否缓存到memchaced,称为smart client,客户端需要知道mysql数据的位置,缓存的位置

http
1.0版本:

客户端到服务器请求数据,后端服务器把数据缓存到缓存服务器并且响应数据给客户端,当下次客户端再次请求相同资源时(如根据rul),则到缓存服务器直接命中。但第一次后端服务器缓存数据到缓存服务器的数据是有缓存时间限制的,即缓存时间的有效期,假如从缓存时起2小时(采用绝对时间),缓存数据有效,当缓存数据有效期过后,则失效,需要再次到后端服务器请求数据,但失效的缓存数据的在后端服务器并不一定改变,则浪费带宽,采用过期机制

1.1版本:

再1.0的基础上,采用文件验证,即缓存数据到期后,检验文件内容的校验码,看是否改变,如没有改变,则失效的缓存数据再次获得2个小时(相对时间)的有效缓存期,此过程只有请求和响应的校验码,节约带宽
  条件式请求:Etag(extend tag)
    If-None-Match 304,not modified或者200 ok ,文件内容不匹配(又称指纹不匹配)
    If-modify-since 304 ,not modified 时间戳改变
1.1版本加入了cache-control
  public缓存:即缓存的内容是可以共享的
  private缓存:缓存的内容不可以共享,涉及私人信息,如cookie,浏览器本地的缓存
  User-Agent <–> private cache <–> public cache <–> public cache 2 <–> Original Server
  Cache-Control: key=value, key=value
缓存有效性判断机制:
  过期时间:Expires
    HTTP/1.0
      Expires:过期
    HTTP/1.1
      Cache-Control: maxage=
      Cache-Control: s-maxage=
  条件式请求:
    Last-Modified/If-Modified-Since:基于文件的修改时间戳来判别;
    Etag/If-None-Match:基于文件的校验码来判别;

客户端浏览器本地缓存,CDN,缓存服务器等多级缓存可以解决客户端80%的请求资源

在代理服务器之前的缓存,对webpage cache开源解决方案
  squid
  varnish 主流

varnish官方站点: http://www.varnish-cache.org/
  Community
  Enterprise
    This is Varnish Cache, a high-performance HTTP accelerator.

程序架构:
  Manager进程 : #管理cahce子进程,升级,管理
  Cacher进程,包含多种类型的线程: #工作进程
  accept, worker, expiry, …
shared memory log:
  统计数据:计数器;
  日志区域:日志记录;
    varnishlog(日志), varnishncsa(ncsa格式日志), varnishstat(统计日志)…

配置接口:VCL
    Varnish Configuration Language, DSL(Domain Specific Language)域专用语言
    vcl complier –> c complier –> shared object
    vcl配置语言,即对varnish的配置文件配置好之后,要生效,需要编译为c语言,再用c语言编译为程序,即可生效

    varnish的每个版本使用都不一样
每个引擎都有自己的专用域配置,即类似iptables中的netfilter的5个勾子
如图4.0版本的图,椭圆形代表一个引擎

两类配置
  配置varnishd守护进程
  配置缓存系统

state engine
  前端:vcl_recv,vcl_pipe(4层代理),vcl_hash(7层代理),vcl_hit,vcl_pass,vcl_purge,vcl_synth,vcl_delive
  后端:vcl_backend_fetch,vcl_backend_response,vcl_backend_error
vcl_init,vcl_fin

[root@varnish ~ ]#yum info varnish
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Available Packages
Name        : varnish
Arch        : x86_64
Version     : 4.0.5
Release     : 1.el7
Size        : 453 k
Repo        : epel1/7
Summary     : High-performance HTTP accelerator
URL         : http://www.varnish-cache.org/
License     : BSD
Description : This is Varnish Cache, a high-performance HTTP accelerator.
            : Documentation wiki and additional information about Varnish is
            : available on the following web site: http://www.varnish-cache.org/

缓存存放
  key,value
    key→keys_zone 内存存放
    value→disk hash url的3级路由寻址,按照文件层级放在磁盘上
    如nginx的缓存功能
  memory
    malloc,free 内核调用内存分配,free为释缓存c语言编写的系统调用
    jemalloc 在2006年为提高低性能的malloc而写的Jemalloc。Jemalloc是从2007年开始以FreeBSD标准引进来的。软件技术革新很多是FreeBSD发起的。在FreeBSD应用广泛的技术会慢慢导入到linux。Redis2.4版本之后,默认使用Jemalloc来做内存管理
  disk
    single bin file
  persistent基于磁盘的持久存储
    disk,experimental

[root@varnish ~ ]#rpm  -ql varnish
/etc/logrotate.d/varnish
/etc/varnish
/etc/varnish/default.vcl
/etc/varnish/varnish.params

/usr/lib/systemd/system/varnish.service
/usr/lib/systemd/system/varnishlog.service
/usr/lib/systemd/system/varnishncsa.service
/usr/sbin/varnish_reload_vcl
/usr/sbin/varnishd
/usr/share/doc/varnish-4.0.5

[root@varnish ~ ]#cd /etc/varnish/
[root@varnish varnish ]#ls
default.vcl  secret  varnish.params

[root@varnish varnish ]#vim varnish.params 
# 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
ARNISH_LISTEN_PORT=6081          #面向后端代理服务器的链接端口

# 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"     #内存管理,256M有点小
#VARNISH_STORAGE="file,/var/lib/varnish/varnish.bin 16G"

# User and group for the varnishd worker processes
VARNISH_USER=varnish
VARNISH_GROUP=varnish

[root@varnish ~ ]#varnishd -h           #帮助文档
[root@varnish ~ ]#varnishadm -h
varnishadm: invalid option -- 'h'
usage: varnishadm [-n ident] [-t timeout] [-S secretfile] -T [address]:port command [...]
    -n is mutually exlusive with -S and -T

[root@varnish ~ ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
    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@varnish varnish ]#vim default.vcl 
backend default {
    .host = "192.168.31.17";
    .port = "8080";
}

[root@varnish varnish ]#varnish_reload_vcl
Loading vcl from /etc/varnish/default.vcl
Current running config name is 
Using new config name reload_2018-09-05T11:05:52
VCL compiled.
VCL 'reload_2018-09-05T11:05:52' now active
available       0 boot
active          0 reload_2018-09-05T11:05:52

Done
[root@varnish varnish ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
vcl.list
200        
available       0 boot
active          0 reload_2018-09-05T11:05:52
vcl.use reload_2018-09-05T11:05:52

[root@cos27 ~ ]#curl 192.168.31.7:6081
<!DOCTYPE html>
<html>
  <head>
    <title>503 Backend fetch failed</title>
  </head>
  <body>
    <h1>Error 503 Backend fetch failed</h1>
    <p>Backend fetch failed</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 3</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

varnish定义缓存命中

[root@varnish varnish ]#vim default.vcl 
backend default {
    .host = "192.168.31.17";
    .port = "80";
}

vcl.use boot
200        
VCL 'boot' now active
vcl.discard reload_2018-09-05T11:05:52
200 

vcl.load dhy1 default.vcl 
200        
VCL compiled.
vcl.use dhy1
200        
VCL 'dhy1' now active

[root@cos27 ~ ]#curl 192.168.31.7:6081
<h1>varnish backend server 31.17</h1>

[root@cos27 ~ ]#curl -I 192.168.31.7:6081
HTTP/1.1 200 OK
Date: Wed, 05 Sep 2018 03:18:25 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 05 Sep 2018 03:09:55 GMT
ETag: "26-575171bdc3afe"
Content-Length: 38
Content-Type: text/html; charset=UTF-8
X-Varnish: 32784 12
Age: 13
Via: 1.1 varnish-v4
Connection: keep-alive

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

[root@varnish varnish ]#vim default.vcl

Done
[root@varnish varnish ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
vcl.load dhy2 default.vcl 
200        
VCL compiled.
vcl.use dhy2
200        
VCL 'dhy2' now active

vcl.show -v dhy2

[root@cos27 ~ ]#curl -I 192.168.31.7:6081
HTTP/1.1 200 OK
Date: Wed, 05 Sep 2018 04:08:04 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 05 Sep 2018 03:09:55 GMT
ETag: "26-575171bdc3afe"
Content-Length: 38
Content-Type: text/html; charset=UTF-8
X-Varnish: 65597 43
Age: 2
Via: 1.1 varnish-v4
X-Cache: HIT via 192.168.31.7       #命中
Connection: keep-alive

不检查缓存

示例1:强制对某类资源的请求不检查缓存:
    vcl_recv {
        if (req.url ~ "(?i)^/(login|admin)") {
            return(pass);
        }
    }

取消图片的cookid

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


后端httpd服务器记录客户端访问的ip地址

示例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;
        }
    }       
在httpd的日志格式配置文件中,添加http.X-Fowarded-For

缓存对象的修剪:purge, ban

   配置purge操作:
   (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;
    "192.168.31.7"/24;
}

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

测试
curl -I 192.168.31.7:6081/index.html
curl -X "PURGE" 192.168.31.7:6081/index.html
curl -I 192.168.31.7:6081/index.html

Banning: 检查匹配的url,只是一次生效

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

    示例:
        ban req.url ~ (?i)^/javascripts
        ban req.url ~ (?I)^/test[456].html$

(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"));
    }   

    curl -X BAN http://www.ilinux.io/test1.html

    ban req.http.host==www.ilinux.io && req.url==/test1.html

如何设定使用多个后端主机:#动静分离

backend default {
    .host = "192.168.31.17";
    .port = "80";
}   backend appsrv {
    .host = "192.168.31.27";
    .port = "80";
}

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

    ...
}

nginx: proxy_pass
haproxy: use_backend

Director:

varnish是http协议代理服务器缓存,也可以做负载均衡

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

示例:
    import directors;    # load the directors       
    backend server1 {
        .host = "192.168.31.17";
        .port = "80";
    }
    backend server2 {
        .host = "192.168.31.27";
        .port = "80";
    }       
    sub vcl_init {
        new websrvs = directors.round_robin();
        websrvs.add_backend(server1);
        websrvs.add_backend(server2);
    }       
    sub vcl_recv {
        set req.backend_hint = websrvs.backend();
    }
    基于随机的调度方式,支持服务器权重:
    #    sub vcl_init {
    #        new websrvs = directors.random();
    #        websrvs.add_backend(srv1,1);
    #        websrvs.add_backend(srv2,2);
    #    }      

会话绑定

基于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:超时时长;
    .expecteesponse:期望的响应码,默认为200;

健康状态检测的配置方式:
    (1) probe PB_NAME  { }
        backend NAME = {
        .probe = PB_NAME;
        ...
            }

        (2) backend NAME  {
            .probe = {
                ...
            }
        }
示例:
    probe check {
            .url = "/customindex.html";
            .window = 5;
            .threshold = 4;
            .interval = 2s;
            .timeout = 1s;
    }
    backend default {
            .host = "192.168.31.7";
            .port = "80";
            .probe = check;
    }
    backend appsrv {
            .host = "192.168.31.27";
            .port = "80";
            .probe = check;
    }

    手动设定BE主机的状态:  #强制设定
        sick:管理down; 
        healthy:管理up;
        auto:probe auto;
                backend.set_health websrv1 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
查看
    param.show thread_pools
    param.show thread_pool_max
    param.show thread_pool_min
    param.set thread_pools 4


永久有效的方法:
    varnish.params #的最后一行
        DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"
        #DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"

varnish日志区域:

shared memory log 
    计数器
    日志信息
命令
    varnishstat
    varnishtop
    varnishncsa
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>:对指定的标签的值基于regex进行过滤; 
    -x taglist:排除列表
    -X  <[taglist:]regex>:对指定的标签的值基于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"):生成响应报文;
    永久保存日志
        systemctl start varnishncsa.service     
        cat /usr/lib/systemd/system/varnishncsa.service
        启动服务即是写到文件中
总结:
    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 {}

补充资料:varnish book
http://book.varnish-software.com/4.0/

基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制问题,并提供完整的Matlab代码实现。文章结合数据驱动方法与Koopman算子理论,利用递归神经网络(RNN)对非线性系统进行建模与线性化处理,从而提升纳米级定位系统的精度与动态响应性能。该方法通过提取系统隐含动态特征,构建近似线性模型,便于后续模型预测控制(MPC)的设计与优化,适用于高精度自动化控制场景。文中还展示了相关实验验证与仿真结果,证明了该方法的有效性和先进性。; 适合人群:具备一定控制理论基础和Matlab编程能力,从事精密控制、智能制造、自动化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于纳米级精密定位系统(如原子力显微镜、半导体制造设备)中的高性能控制设计;②为非线性系统建模与线性化提供一种结合深度学习与现代控制理论的新思路;③帮助读者掌握Koopman算子、RNN建模与模型预测控制的综合应用。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现流程,重点关注数据预处理、RNN结构设计、Koopman观测矩阵构建及MPC控制器集成等关键环节,并可通过更换实际系统数据进行迁移验证,深化对方法泛化能力的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值