热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Varnish服务器配置实例

网络上称Varnish是一款高性能的开源HTTP加速器,与大家耳熟能详的squid有着类似的功能,下面来看Varnish的特点:是基于内存缓存,重启后数据将消失。利用虚拟内存方式,io性能好。支持设置0~60秒内的精确缓存时间。VCL配置管理比较灵活。32位机器上缓存

网络上称Varnish是一款高性能的开源HTTP加速器,与大家耳熟能详的squid有着类似的功能,下面来看Varnish的特点:

是基于内存缓存,重启后数据将消失。

利用虚拟内存方式,io性能好。

支持设置0~60秒内的精确缓存时间。

VCL配置管理比较灵活。

32位机器上缓存文件大小为最大2G。

具有强大的管理功能,例如top,stat,admin,list等。

状态机设计巧妙,结构清晰。

利用二叉堆管理缓存文件,达到积极删除目的。

Varnish的Storage方式可分为两种:

Malloc 通过malloc获取内存。

Mmap file 创建大文件,通过二分法分段映射成1G以内的大块。

Varnish工作流程:

与一般服务器软件类似,分为master(management)进程和child(worker,主要做cache的工作)进程。master进程读入命令,进行一些初始化,然后fork并监控child进程。child进程分配若干线程进行工作,主要包括一些管理线程和很多woker线程。

针对文件缓存部分,master读入存储配置(-s file[,path[,size[,granularity]]] ),调用合适的存储类型,然后创建/读入相应大小的缓存大文件。接着,master初始化管理该存储空间的结构体。这些变量都是全局变量,在fork以后会被child进程所继承(包括文件描述符)。

在child进程主线程初始化过程中,将前面打开的存储大文件整个mmap到内存中(如果超出系统的虚拟内存,mmap失败,进程会减少原来的配置mmap大小,然后继续mmap),此时创建并初始化空闲存储结构体,挂到存储管理结构体,以待分配。

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

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

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

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

VCL内置函数:

vcl_recv:用以接受和处理请求,当请求接收成功后被调用,作用有

1、修改客户端数据以减少缓存对象的差异性;如某些缓存内容中的COOKIE,

2、基于客户端数据选用缓存策略;如缓存特定的url,不缓存POST请求;

3、为某web应用程序执行url重写;

4、挑选合适的后端web服务器;

接下来的动作有:

pass:将请求直接传递给后端主机,后端主机应答后送给客户端,不进行任何缓存,在当前连接下,每次都返回新的内容。

pipe:不对客户端进行检查或作出任何操作,而是在client和后端server建立专用管道。

lookup:在缓存中查找请求的对象,如果缓存中没有,后续操作很可能将请求的对象进行缓存。

error:由varnish自己发送一个响应报文,一般是响应一个错误类信息,重定向类信息,或负载均衡器返回的后端web服务器健康状态检查类信息;

vcl_pipe:

用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个链接关闭。

此函数一般以如下几个关键字结束:

error code [reason]

pipe

vcl_pass:

用于将请求直接传递至后端主机,后端主机应答数据后送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。

此函数一般以如下几个关键字结束:

error code [reason]

pass:

lookup:表示在缓存中查找请求的对象,根据结果把控制权交给vcl_hit或vcl_miss

vcl_hit:在执行lookup指令后,如果在缓存中找到请求的资源,将自动调用此函数,后续动作有:

deliver:表示将找到的内容发送给客户端,并将控制权交给vcl_deliver

error code [reason]

pass:将请求直接传递给后端主机,后端主机应答后送给客户端,不进行任何缓存,在当前连接下,每次都返回新的内容。

vcl_miss:没有在缓存中找到请求的资源,后续动作有:

fetch:从后端取内容

error code [reason]

pass

vcl_fetch:从后端主机获取用户请求的资源,后续动作有:

error code [reason]

pass

deliver

图解varnish工作流程:

Varnish配置实例

varnish常用变量:

当处理一个请求时的变量:

client.ip # 客户端IP

client.identity # 客户端id,通常为用户名等信息;

server.hostname # 请求首部中的主机名(代理服务器的)

server.identity# server id

server.ip # 代理服务器的IP

server.port # 端口

req.request #请求的方法“GET/HEAD/POST/PUT....”

req.url # 请求的url

req.proto # 请求的协议版本;

req.backend # 响应请求时使用的后端主机;

req.restarts # 请求重启的次数,原因可能是被重定向

req.http.header # 对应的请求首部

安装启动Varnish

[root@node1 ~]# yum -y localinstall varnish-3.0.4-1.el6.x86_64.rpm varnish-libs-3.0.4-1.el6.x86_64.rpm
# 配置文件详解
[root@node1 ~]# vim /etc/sysconfig/varnish
# Configuration file for varnish
# varnish进程可以打开的文件个数,因为每个套接字连接需要2个文件,分为前端和后端,所以最大为5536*2
NFILES=131072
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
# 内存中默认划分给varnish使用的内存;
MEMLOCK=82000
# Maximum number of threads (for ulimit -u)
# 可以启动的线程个数,无限制;
NPROCS="unlimited"
# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
# DAEMON_COREFILE_LIMIT="unlimited"
# Set this to 1 to make init script reload try to switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short,
# use Alternative 3, Advanced configuration, below
# 不用重启varnish就可以使配置文件生效,需要使用CLI连接
RELOAD_VCL=1
#
# # Main configuration file. You probably want to change it :)
#  varnish配置文件路径
VARNISH_VCL_COnF=/etc/varnish/default.vcl
#
# VARNISH_LISTEN_ADDRESS=
# Varnish监听端口,一般设置为80
VARNISH_LISTEN_PORT=6081
#
# # Telnet admin interface listen address and port
# varnish管理接口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#
# # Shared secret file for admin interface
# 管理varnish时用的的秘钥文件
VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # The minimum number of worker threads to start
# varnish最少线程数
VARNISH_MIN_THREADS=50
#
# # The Maximum number of worker threads to start
# varnish最大线程数;
VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# 线程超时时间
VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# 存储文件
VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# 存储文件大小:
VARNISH_STORAGE_SIZE=1G
VARNISH_MEMORY_SIZE=64M
#
# # Backend storage specification
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}"
#
# # Default TTL used when the backend does not specify
#
## Alternative 4, Do It Yourself. See varnishd(1) for more information.
#
# DAEMON_OPTS=""
[root@node1 ~]# service varnish start
[root@node1 ~]# cat /etc/sysconfig/varnish
# Configuration file for varnish
# varnish进程可以打开的文件个数,因为每个套接字连接需要2个文件,分为前端和后端65536X2
NFILES=131072
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
# 内存中默认划分给varnish使用的内存;
MEMLOCK=82000
# Maximum number of threads (for ulimit -u)
# 可以启动的线程个数,无限制;
NPROCS="unlimited"
# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
# DAEMON_COREFILE_LIMIT="unlimited"
# Set this to 1 to make init script reload try to switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short,
# use Alternative 3, Advanced configuration, below
# 不用重启varnish就可以使配置文件生效,需要使用CLI连接
RELOAD_VCL=1
#
# # Main configuration file. You probably want to change it :)
#  varnish配置文件路径
VARNISH_VCL_COnF=/etc/varnish/default.vcl
#
# VARNISH_LISTEN_ADDRESS=
# Varnish监听端口,一般设置为80
VARNISH_LISTEN_PORT=6081
#
# # Telnet admin interface listen address and port
# varnish管理接口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#
# # Shared secret file for admin interface
# 管理varnish时用的的秘钥文件
VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # The minimum number of worker threads to start
# varnish最少线程数
VARNISH_MIN_THREADS=50
#
# # The Maximum number of worker threads to start
# varnish最大线程数;
VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# 线程超时时间
VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# 存储文件
VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# 存储文件大小:
VARNISH_STORAGE_SIZE=1G
VARNISH_MEMORY_SIZE=64M
#
# # Backend storage specification
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}"
#
# # Default TTL used when the backend does not specify
#
## Alternative 4, Do It Yourself. See varnishd(1) for more information.
#
# DAEMON_OPTS=""
#
[root@node1 ~]# service varnish start

二、VCL(varnish configuration language)

Varnish ConfigurationLanguage (VCL)是varnish配置缓存策略的工具,它是一种基于“域”(domainspecific)的简单编程语言,它支持有限的算术运算和逻辑运算操作、允许使用正则表达式进行字符串匹配、允许用户使用set自定义变量、支持if判断语句,也有内置的函数和变量等。使用VCL编写的缓存策略通常保存至.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。事实上,整个缓存策略就是由几个特定的子例程如vcl_recv、vcl_fetch等组成,它们分别在不同的位置(或时间)执行,如果没有事先为某个位置自定义子例程,varnish将会执行默认的定义。

VCL策略在启用前,会由management进程将其转换为C,而后再由gcc编译器将C编译成二进制程序。编译完成后,management负责将其连接至varnish实例,即child进程。正是由于编译工作在child进程之外完成,它避免了装载错误格式VCL的风险。因此,varnish修改配置的开销非常小,其可以同时保有几份尚在引用的旧版本配置,也能够让新的配置即刻生效。编译后的旧版本配置通常在varnish重启时才会被丢弃,如果需要手动清理,则可以使用varnishadm的vcl.discard命令完成。

VCL语法:

(1)//、#或/* comment*/用于注释
(2)sub $name定义函数
(3)不支持循环,有内置变量
(4)使用终止语句,没有返回值
(5)域专用
(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)

修改配置文件后可以不用重启服务就可以生效,通过CLI工具:

[root@node1 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,2.6.32-358.el6.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-3.0.4 revision 9f83e8f
Type 'help' for command list.
Type 'quit' to close CLI session.
varnish>
# varnish 运行参数设定:
varnish> param.show
# thread_pool_max 默认最多启动1000个
# thread_pools    默认线程池个数,建议跟CPU核心数相同
#listen_depth 当线程池空了后,后续连接在队列中,这里就是定义队列的长度
# lru_interval 默认清理缓存的时间为2s。(根据lru算法计算)
# 设置参数(重启后失效)
varnish> param.set thread_pools 4
200

配置实例:

# 定义健康状况监测
probe healthcheck {
        .url = "/";
        .interval = 6s;
        .timeout = 0.3s;
        .window = 8;
        .threshold = 3;
        .initial = 3;
}
定义后端主机
backend web1 {
  .host = "172.16.1.7";
  .port = "80";
  .probe = healthcheck;
}
backend web2 {
  .host = "172.16.1.3";
  .port = "80";
  .probe = healthcheck;
}
backend app1 {
  .host = "172.16.1.7";
  .port = "8080";
  .probe = healthcheck;
}
backend app2 {
  .host = "172.16.1.3";
  .port = "8080";
  .probe = healthcheck;
}
# 定义负载均衡集群,random为算法
director webserver  random {
        {.backend = web1;
         .weight  = 2;
        }
        {.backend = web2;
         .weight = 5;
        }
}
director appserver  random {
        {.backend = app1;
         .weight = 2;}
        {.backend = app2;
         .weight = 5;}
}
#The DNS director
director directorname dns {
        .list = {
                .host_header = "www.example.com";
                .port = "80";
                .connect_timeout = 0.4s;
                "172.16.1.0"/24;
                "172.16.100.128"/25;
        }
        .ttl = 5m;
        .suffix = "internal.example.net";
}
# The fallback director
director b3 fallback {
  { .backend = www1; }
  { .backend = www2; } // will only be used if www1 is unhealthy.
  { .backend = www3; } // will only be used if both www1 and www2
                       // are unhealthy.
}
# PURGE,清理缓存
acl purge {
  "localhost";
  "172.16.1.0"/24;
}
sub vcl_recv {
  if (req.request == "PURGE") {
    if (!client.ip ~ purge) {
      error 405 "Not allowed.";
    }
    return(lookup);
  }
}
sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}
sub vcl_miss {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}
可以使用:curl -X PURGE -I  http://172.16.1.1/index.html
# 防盗链:
if (req.http.referer  ~  "http://.*") {
    if (!(req.http.referer  ~  "http://.*\.magedu.com" || req.http.referer  ~  "http://.*\.google\.com.*)) {
        set req.http.host = "www.magedu.com";
        set req.url = "/anti/anti.html";
        }
    }
# 设置新的响应头部,显示命中或丢失
sub vcl_deliver {
        if (obj.hits > 0) {
         set resp.http.X-Cache = "HIT";
   } else {
         set resp.http.X-Cache = "MISS";
}
}
# 为后端主机传递客户端IP,并设置动静分离:
sub vcl_recv {
if (req.http.x-forwarded-for) {
           set req.http.X-Forwarded-For =
                          req.http.X-Forwarded-For + ", " + client.ip;
                  } else {
                      set req.http.X-Forwarded-For = client.ip;
                 }
   if (req.url ~ "\.php$"){
        set req.backend = appserver;
}else{
        set req.backend = webserver;
}
#当url中包含servlet时,不进行缓存。
    if (req.url ~ "^/servlet/") {
        return (pass);
    }
#当url中包含services时,不进行缓存。
    if (req.url ~ "^/services/") {
        return (pass);
    }
#对于请求类型是GET,并且请求的URL中包含upload,那么就进行缓存,缓存的时间是300秒
    if (req.request == "GET" && req.url ~ "^/upload(.*)$") {
       set beresp.ttl = 300s;
    }
#对于请求类型是GET,并且请求的URL以png、xsl、xml、gif、css、js等结尾时,则进行缓存,缓存时间为600秒。
    if (req.request == "GET" && req.url ~ "\.(png|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg|css|js|html|htm)$") {
       set beresp.ttl = 600s;
    }
    return (deliver);
}
推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • 本文介绍了5个基本Linux命令行工具的现代化替代品,包括du、top和ncdu。这些替代品在功能上进行了改进,提高了可用性,并且适用于现代化系统。其中,ncdu是du的替代品,它提供了与du类似的结果,但在一个基于curses的交互式界面中,重点关注占用磁盘空间较多的目录。 ... [详细]
  • 护墙_搭建LVS负载均衡NAT和DR模式
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了搭建LVS负载均衡NAT和DR模式相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 进入配置文件目录:[rootlinuxidcresin-4.0.]#cdusrlocalresinconf查看都有哪些配置文件:[rootlinuxid ... [详细]
  • 在单位的一台4cpu的服务器上部署了esxserver,挂载了6个虚拟机,目前运行正常。在安装部署过程中,得到了cnvz.net论坛精华区 ... [详细]
  • k8s+springboot+Eureka如何平滑上下线服务
    k8s+springboot+Eureka如何平滑上下线服务目录服务平滑上下线-k8s版本目录“上篇介绍了springboot+Euraka服务平滑上下线的方式,有部分小伙伴反馈k ... [详细]
  • Linux 服务器修改用户名
    Linux服务器修改用户名1、编辑名称vimetchostname2、保存编辑并退出wq3、重 ... [详细]
  • 对于一般的扩展包,我们一般直接pipinstallxxx即可安装,但是unrar直接安装后,发现并不能通过Python程序实现解压的功能& ... [详细]
author-avatar
贝贝不离
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有