Varnish

Varnish

Varnish官方网站

管理进程:编译VCL并应用新配置,监控varnish,初始化varnish, CLI接口

Child/cache:

  1. Acceptor: 接收新的连接请求
  2. worker threads: 处理用户请求
  3. Expiry: 清理缓存中的过期对象

日志:Shared Memory Log,共享内存日志大小默认一般为90MB,分为两步分,前一部分为计数器,后一部分为请求相关的数据。

VCL:Varnish Configuration Language 域风格简单配置语言,缓存策略配置接口

varnish如何存储缓存对象:

  1. file:单个文件,不支持持久机制,重启之后缓存全部失效
  2. malloc:内存,把所有缓存对象缓存在内存中
  3. persistent:基于文件的持久存储

配置varnish的三种应用:

  1. varnishd应用程序的命令行参数:监听的socket,使用的存储类型等等,额外的配置参数: -p param=value -r param,param设定只读参数列表

    /etc/varnish/varnish.params

  2. -p选项指明的参数:

    运行时参数:可在程序运行中,通过CLI进行配置

  3. vcl:配置缓存系统的缓存机制:

    通过vcl配置文件进行配置,先编译,后应用,依赖于c编译器

    /etc/varnish/default.vcl

命令行工具:

​ varnishadm -S /etc/varnish/secret -T IP:PORT

​ Log:

​ varnishlog

​ varnishncsa

​ Statistics

​ varnishstat

​ Top:

​ varnishtop

vcl:

  1. state engine:各引擎之间存在一定的相关性:前一个engine如果有多个下游engine,则上游engine需要用return指明要转移的下游engine
    • vcl_recv
    • vcl_hash
    • vcl_hit
    • vcl_miss
    • vcl_fetch
    • vcl_diliver
    • vcl_pipe
    • vcl_pass
    • vcl_error

vcl编程语法:

​ //,#, /* */用于注释,会被编译器忽略

​ sub $name: 用于定义子例程

​ 不支持循环

​ 有众多内置的变量,变量的可调用位置与state engine有密切的相关性

​ 支持终止语句,return(action):没有返回值

​ 域专用

​ 操作符= , == , &&,~,||, !

​ 条件判断语句:

​ if (condtion) {

​ } else {

​ }

​ 变量赋值:set name=value

​ unset name

​ req.http.HEADER: 调用request报文中http协议的指定的HEADER首部

​ req.http.X-Forwarded-For

​ req.http.Authorization

​ req.http.cookie

​ req.request: 请求方法

​ client.ip : 客户端IP

state engine 流程(v3);

  1. vcl_rec –> vcl_hash –>vcl_hit –> vcl_deliver 缓存命中 varnish直接投递
  2. vcl_recv –> vcl_hash–> vcl_miss –> vcl_fetch –> vcl_deliver 缓存没有命中,从后端服务器去取
  3. vcl_recv –> vcl_pass –> vcl_fetch –> vcl_deliver 强制到后端服务器取数据
  4. vcl_recv –> vcl_pipe 理解不了客户端的请求 ,直接发送给后端服务器,实现管道

state engine (v4)

  1. vcl_recv
  2. vcl_pass
  3. vcl_pipe
  4. vcl_pipe
  5. vcl_hit
  6. vcl_miss
  7. vcl_backend_fetch
  8. vcl_backend_response
  9. vcl_backerd_error
  10. vcl_purge
  11. vcl_systh

定义在vcl_deliver中,向响应给客户端的报文添加一个自定的首部X-Cache来显示是否命中缓存

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

varnish的内置变量

  1. req 客户端发送的请求

  2. resp 响应客户端相关变量

  3. bereq开头变量 向后端服务器取资源

  4. beresp 开头变量 ,收到的后端服务器的响应报文

  5. server开头变量 varnish本身

  6. obj开头变量 从后端服务器收到响应以后其中内容的属性

  7. storage

    breq:

    • bereq.http.HEADERS: 由varnish发往backend server 的请求报文的指定首部
    • bereq.requests :请求方法
    • bereq.url
    • bereq.proto: 使用的协议版本 http/1.1 1.0

    beresp:

    • beresp.proto 后端服务器响应式的协议版本
    • beresp.http.HEADER: 从backend server 响应的报文的首部
    • beresp.backend.ip 后端服务器的IP
    • beresp.backend.name 后端服务器的主机名称
    • beresp.reason 后端服务器的响应原因短语
    • beresp.status 后端服务器的响应状态码
    • beresp.ttl 后端服务器响应对象剩余的生存时长
    • bereq.backend: 指明要调用的后端主机

    obj:

  • obj.hits: 缓存对象命中次数

  • obj.ttl: 对象的TTL值

    req:

  • req.method: 请求的方法

    resp:

  • resp.status

    server:

  • server.ip varnish服务器IP

  • server.hostname 服务器的主机名

    storage:

  • storage..free_space: 剩余空间

  • storage..used_space 已用空间

    详细参考官方文档

    设置支持虚拟主机:

​ if (req.http.host == “www.linux.com”) {

​ }

强制对某资源的请求,不检查缓存:

if (req.url ~ “^test7.html$”) {
	return(pass);
}		

不允许缓存,/admin 和 /login的请求

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

对特定类型的资源取消其私有的cookie标识(放在vcl_backend_response中),并强行设定其可以varnish缓存的时长:

if (beresp.http.cache-control !~ "s-maxage") {
    if (bereq.url ~ "(?i)\.jpg$") {
        set beresp.ttl = 3600s;
        unset beresp.http.Set-Cookie;
    }
    if (bereq.url ~ "(?i)\.css$") {
        set beresp.ttl = 600s;
        unset beresp.http.Set-Cookie;
    } 
}

backend server的定义:

  • backend name {

    .attribute = “value”;

    }

.host: BE主机的IP

.port BE主机监听的端口

.probe: 对BE做健康状态检测

.max_connections: 并发连接最大数量

后端主机的健康检测方式:

probe name {

​ .attribute = “value”;

}

.url : 判定BE健康有要请求的URL

.expected_response : 期望的响应状态码 默认为200

动静分离示例配置

vcl 4.0;

backend websrv1 {
    .host = "192.168.175.5";
    .port = "80";
    .probe =  {
        .url = "/test1.html";
}
}
backend websrv2 {
    .host = "192.168.175.4";
    .port = "80";
    .probe = {                          #设置健康检查的文件
        .url = "/test1.html";
}
}


sub vcl_recv {
    if  (req.url ~ "(?i)^/login" || req.url ~ "(?i)^/admin") { #如果以admin或login开头就不缓存
        return(pass);
}
    if (req.url ~ "(?i)\.(jpg|png|gif)$") {         #动静分离配置
        set req.backend_hint = websrv1;          
}else {
        set req.backend_hint = websrv2;
}

}

sub vcl_backend_response {
}

sub vcl_deliver {
    if (obj.hits>0) {

        set resp.http.X-Cache = "HIT";
}else{

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

示例2:负载均衡配置

vcl 4.0;

backend websrv1 {
    .host = "192.168.175.5";
    .port = "80";
    .probe =  {
        .url = "/test1.html";
}
}
backend websrv2 {
    .host = "192.168.175.4";
vcl 4.0;

backend websrv1 {
    .host = "192.168.175.5";
    .port = "80";
    .probe =  {
        .url = "/test1.html";
}
}
backend websrv2 {
    .host = "192.168.175.4";
    .port = "80";
    .probe = {
        .url = "/test1.html";
}
}
import directors;
sub vcl_init {
        new mycluster = directors.round_robin();
        mycluster.add_backend(websrv1);
        mycluster.add_backend(websrv2);
}


sub vcl_recv {
        set req.backend_hint = mycluster.backend();

}

sub vcl_backend_response {
}

sub vcl_deliver {
    if (obj.hits>0) {

        set resp.http.X-Cache = "HIT";
}else{

        set resp.http.X-Cache = "Miss";
}
}
#注意此处是对资源的负载均衡而不是对单个文件的负载均衡,访问一个文件到1服务器,访问另一个负载到2服务器(有点坑爹)

负载均衡算法:

  1. fallback
  2. random
  3. round_robin
  4. hash

掌握:varnishlog, varnishncsa, varnishtop, varnishstat

posted @ 2018-10-10 00:59  谭普利特  阅读(345)  评论(0编辑  收藏  举报