Varnish是一个轻量级的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点,现在的Varnish总共代码量不大,功能上虽然在不断改进,但是还需要继续丰富和加强。下面总结了Varnish的一些特点:
(1)是基于内存缓存,重启后数据将消失。
(2)利用虚拟内存方式,io性能好。
(3)支持设置0~60秒内的精确缓存时间。
(4)VCL配置管理比较灵活。
(5)32位机器上缓存文件大小为最大2G。
(6)具有强大的管理功能,例如top,stat,admin,list等。
(7)状态机设计巧妙,结构清晰。

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

两篇文章

高负载网站之Varnish与Drupal–基本篇
Varnish构建高负载Drupal网站–高级篇

Varnish缓存操作,一般有两个方法,
1. 在varnish的配置文件设置。
2. 通过http协议指定,比如Control-Cache。

第一种方法耦合性较低,只需修改vcl即可,但是灵活性较差,如果要独立设置每个页面的ttl可能比较麻烦。
第二种方法较为灵活,可以设置每一个页面的缓存时间,比如Control-Cache: max-age=10. (缓存10秒),缺点就是耦合性,既要在PHP端设置,又要在Varnish里面设置。

小插曲:如果使用Control-Cache: max-age=10这种方式缓存的话,varnish可以缓存,但是会出现一个问题,客户端的浏览器同样会缓存,如果不让客户端浏览器缓存,而只让varnish缓存,可以使用 Control-Cache: max-age=0; s-maxage:10.

这里,我们选择使用VCL,也就是上面所说的第一种方法来缓存http动态页面。
如下假设:
a) 要缓存的页面url为 /abc/* 的形式,
b) 只缓存匿名用户的页面(登录用户以后再介绍)
c) 登录用户需要有一个独有的cookie,如DRUPAL_UID=11

1. 在vcl_recv里面添加如下代码(此处,一定要将登录用户的请求pass到后端服务器,否则,也会得到缓存页面,因为varnish的hash默认没有cookie,所以登录用户同样会命中匿名用户的缓存数据)。
2. 在vcl_fetch里面添加如下代码

if (req.request == "GET" && req.http.Cookie !~ "DRUPAL_UID=[1-9][0-9]*" && req.url ~ "^/abc/.*") {
    unset beresp.http.Pragma;
    unset beresp.http.Expires;
    unset beresp.http.set-cookie;
    set beresp.ttl = 2h; #time to live
    set beresp.do_gzip = true;
    set beresp.grace = 20m; #grace time
    return (deliver);
  }
在vcl_fetch里面注意,最好把set-cookie unset掉,这样就不会修改客户端的cookie了(一般情况,varnish向后台用户发送的是匿名请求,这样set-cookie肯定是一个匿名的session信息,如果当前用户是登录用户,就会导致当前用户logout,这点特别注意)。

这样,就在varnish里面强制缓存了所有/abc/开始的页面内容,缓存时间为2小时。

最后补充一个vcl的调试技巧,在varnish3.x里面引入了std模块,varnish vmod_std包含了一些常用函数,所以调试vcl的时候,我们可以使用std.syslog(1, xxx)等语句,将某个变量记录到syslog里面(/var/log/messages),方便观察结果。

在Varnish的设置中,理解其处理http请求的过程非常重要,因此,这里贴一张VCL的流程图,以便更好的理解varnish处理的过程。

Varnish实践部署

Varnish编译安装

首先需要建立Varnish用户以及用户组来运行Varnish,并且创建Varnish缓存目录和日志目录。

useradd  -s /sbin/nologin varnish

mkdir /data/varnish/cache

mkdir /data/varnish/log

chown -R varnish:varnish  /data/varnish/cache

chown -R varnish:varnish  /data/varnish/log

Varnish的官方网址为http://varnish-cache.org,可以在这里下载最新版本的软件。在安装Varnish前需要安装PCRE库。如果没有安装该库,在Varnish 2以上版本编译时,就会提示找不到PCRE库。PCRE库则可以兼容正则表达式,所以必须先安装。下面介绍其安装过程。

tar zxvf pcre-XXX.tar.gz

cd pcre-XXX/

./configure –prefix=/usr/local/pcre/

make && make install

安装完PCRE库以后,接下来安装Varnish。

tar -zxvf varnish-2.1.X.tar.gz

cd varnish-2.1.X

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

./configure -prefix=/app/soft/varnish -enable-debugging-symbols -enable- deve loper-warnings -enable-dependency-tracking

make

make install

cp redhat/varnish.initrc  /etc/init.d/varnish

cp redhat/varnish.sysconfig  /etc/sysconfig/varnish

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 这一行一定要有,不然在编译的时候会报错。这一行用于指定Varnish查找PCRE库的路径,如果PCRE安装到其他路径下,在这里指定即可,Varnish默认查找PCRE库的路径为/usr/local/lib/pkgconfig。

最后面的两行是复制Varnish的相关脚本,用于脚本的初始化、启动、停止等。

Varnish安装完毕。

Varnish配置文件详解

Varnish需要在多台服务器上缓存数据,就需要Varnish映射所有的URL到一台单独的主机。

backend webserver {

.host = ”127.0.0.1″;

.port = ”80″;

.connect_timeout = 4s;

.first_byte_timeout = 5s;

.between_bytes_timeout = 20s;

}

该块配置用于定义一台Varnish默认访问的后端服务器,当Varnish需要从后端服务器获取数据时,就会访问自己的80端口。

当然Varnish也可以定义多台后端服务器实现负载均衡的目的。

.connect_timeout定义的是等待连接后端的时间

.first_byte_timeout定义的是等待从backend传输过来的第一个字节的时间

.between_bytes_timeout 定义的是两个字节的间隔时间

当然还可以增加一个backend,用于访问本机的8090端口,假设通过该端口提供图片服务。

backend img {

.host = ”127.0.0.1″;

.port = ”8090″;

}

当匹配img的URL时,需把请求发送到上面定义的backend img,其他的请求发送到backend webserver。

sub vcl_recv {

if (req.url ~ ”^/img/”) {

set req.backend = img;

} else {

set req.backend = webserver.

}

}

Varnish不仅仅可以定义多个backend,还可以把多个backend合成一个组,使用循环的方式把请求分配给组中的backends。并且Varnish会根据健康检查情况来判断后端服务器是否正常提供服务。

Varnish使用区域语言VCL来管理定义Varnish的存取策略。VCL语法简单,跟Perl比较相似,可以使用多种运算符如“=”、“==”、“!,&&,!!”等形式;也可以使用正则表达式来进行匹配,还可以使用“set”来指定变量。当执行VCL时,Varnish会先把VCL转换成二进制代码。

有一点要注意,“\”字符在VCL里没有什么特别的含义,这点和其他语言不同。另外,VCL只是配置语言,并不是真正的编程语言,所以没有循环和自定义变量。

为了可以更好地对Varnish进行配置调整,需要了解Varnish的配置语法,也就是VCL语言。下面对VCL常用的一些函数和变量进行介绍。

(1)vcl_recv模块

用于接收和处理请求。当请求成功被调用后,Varnish通过判断请求的数据来决定如何处理请求。此模块一般以如下几个关键字结束。

  • pass:表示进入pass模式,把请求交给vcl_pass模块处理。
  • pipe:表示进入pipe模式,把请求交给vcl_pipe模块处理。

error code [reason]:表示把错误标识返回给客户端,并放弃处理该请求。错误标识包括200、405等。“reason”是对错误的提示信息。

(2)vcl_pipe模块

此模块在请求进入pipe模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,也就是在当前连接未关闭时,服务器将不变的内容返回给客户端,直到该连接被关闭。

(3)vcl_pass模块

此模块表示当请求被pass后,用于将请求直接传递至后端应用服务器。后端应用服务器在接收请求后将数据发送给客户端,但不进行任何数据的缓存,在当前连接下每次都返回最新的内容。

(4)lookup

一个请求在vcl_recv中被lookup后,Varnish将在缓存中提取数据。如果缓存中有相应的数据,就把控制权交给vcl_hit模块;如果缓存中没有相应的数据,请求将被设置为pass并将其交给vcl_miss模块。

(5)vcl_hit模块

执行lookup指令后,Varnish在缓存中找到请求的内容后将自动调用该模块。

在此模块中,deliver表示将找到的数据发送给客户端,并把控制权交给vcl_deliver模块。

(6)vcl_miss模块

执行lookup后,Varnish在缓存中没有找到请求的内容时会自动调用该方法。此模块可以用于判断是否需要从后端服务器获取内容。

在此模块中,fetch表示从后端获取请求的数据,并把控制权交给vcl_fetch模块。

(7)vcl_fetch模块

在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。

(8)vcl_deliver模块

当一个没有被缓存的数据交付给客户端的时候被调用。

(9)vcl_timeout 模块

在缓存数据到期前调用此模块。

在此模块中,discard表示从缓存中清除到期数据。

(10)vcl_discard模块

在缓存数据到期后或缓存空间不够时,自动调用该模块。

在此模块中keep表示将数据继续保留在缓存中。

acl purge {

“localhost”;

“127.0.0.1″;

“18.81.12.10″;

}

if (req.request == ”PURGE”) {

if (!client.ip ~ purge) {

error 405 ”Not allowed.”;

}

return(lookup);

}

这两个规则定义了允许哪些主机通过HTTP来执行PURG进行缓存删除。如果不是指定的IP,就会出现HTTP 405错误,提示Not allowed错误字样。

if (req.http.host ~ ”^(read)?.aaa.com$”) {

set req.backend = webserver;

if (req.request != ”GET” && req.request != ”HEAD”) {

return(pipe);

}

else {

return(lookup);

}

}

else {

error 404 ” Cache Server”;

return(lookup);

}

这段条件判断用于对aaa.com域名进行缓存加速,aaa.com是泛指概念,也就是说所有以aaa.com结尾的域名都进行缓存。而if (req.request != ”GET” && req.request != ”HEAD”) 表示“如果请求的类型不是GET与HEAD”,则返回错误码404。

if (req.url ~ ”^/images”) {

unset req.http.cookie;

}

这条规则的意思是清除服务器上/images目录下的所有缓存,当这个请求在后端服务器生效时,如果访问的URL匹配这个规则,那么头信息中的cookie就会被删除。

if (req.request == ”GET” && req.url ~ ”\.(png|swf|txt|png|gif|jpg|css|js|htm| html)$”) {

unset req.http.cookie;

}

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

因为Squid、Varnish都会把客户端的IP地址放在HTTP_X_FORWARDED_FOR里面传给后端的Web服务器,所以后端的Web程序都要对其进行调用。

if (req.request != ”GET” &&

req.request != ”HEAD” &&

req.request != ”PUT” &&

req.request != ”POST” &&

req.request != ”TRACE” &&

req.request != ”OPTIONS” &&

req.request != ”DELETE”) {

return (pipe);

}

该if判断表示如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,则进入pipe模式。注意这里的“&&”是与的关系。

if (req.request == ”GET” && req.url ~ ”\.(png|swf|txt|png|gif|jpg|css|js|htm| html)”) {

set beresp.ttl = 180s;

}

else {

set beresp.ttl = 30d;

}

return (deliver);

}

该if判断用于对请求类型是GET,并且请求的URL以png、swf、txt、gif、css、js等结尾时,则进行缓存,缓存时间为180秒。其他缓存为30天。

sub vcl_deliver {

set resp.http.x-hits = obj.hits ;

if (obj.hits > 0) {

set resp.http.X-Cache = ”HIT read.easouu.com”;

}

else {

set resp.http.X-Cache = ”MISS read.easou.com”;

}

这个模块定义的是添加一个Header标识,以判断缓存是否命中。

sub vcl_error {

set obj.http.Content-Type = ”text/html; charset=utf-8″;

synthetic {”

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Strict//EN” ”http://www.w3.org/TR/ xhtml1/DTD/xhtml1-strict.dtd”>

<html>

<head>

<title>”} obj.status ” ” obj.response {“</title>

</head>

<body>

<h1>Error ”} obj.status ” ” obj.response {“</h1>

<p>”} obj.response {“</p>

<h3>Guru Meditation:</h3>

<p>XID: ”} req.xid {“</p>

<hr>

<address>

<a href=”http://read.easou.com/”>read.easou.com</a>

</address>

</body>

</html>

“};

return (deliver);

}

最后这个模块定义了访问错误页面时的返回信息。

现在varnish配置基本完成,可以在8080端口上启动varnish,并进行一些基本的测试。

Varnish启动等管理工具

一般情况下,启动Varnish的命令为:

varnishd  -f /etc/varnish/default.vcl  -s malloc,2G -T 127.0.0.1:2000 -a 0.  0.0.0:8080

-f / etc/varnish/default.vcl

–f选项用于指定Varnishd使用的配置文件的路径。

-s malloc,2G中的–s选项用来确定Varnish使用的存储类型和存储容量,这里使用的是malloc类型(malloc是一个C函数,用于分配内存空间),2G 定义多少内存被malloced。

-T 127.0.0.1:2000是Varnish基于文本方式的一个管理接口,启动后可以在不停止Varnish的情况下来管理Varnish。管理端口2000可以指定。因为不是任何人都可以访问Varnish管理端口,所以这里推荐只监听本机端口。

-a 0.0.0.0:80中-a选项表示Varnish监听所有IP发给80端口的HTTP请求。

varnishd -n /app/soft/varnish/cache -f /app/soft/varnish/etc/varnish/vcl.conf -a 0.0.0.0:80 -s file,/app/soft/varnish/cache/varnish_cache.data,5G -u daemon -w 2,65536,60 -T 127.0.0.1:3600 -p thread_pool_min=200 -p thread_pool_max=4000 -p thread_pools=4 -p thread_pool_add_delay=2 -p listen_depth=4096 -p lru_interval=20

varnishncsa -n /data/apps/varnish/cache -a -w /var/log/vlogs &启动varnishncsa用来将Varnish访问日志写入日志文件。

-a address:port # Varnishd命令用于指定监听的地址及其端口

-b address:port #命令用于指定后台服务器地址及其端口

-d # 使用debug模式

-f file # varnishd服务器存取规则文件

-F # 在后台运行

-P file # PID文件

-p param=value # 服务器参数,用来优化性能

-s kind[,storageoptions] # 缓存内容存放方式

-s file,使用文件做为缓存,其路径、大小等

-T address:port # telnet管理地址及其端口

现在Varnish已经正常运行,以上主要解释了使用内存作为存储方式启动命令行,也是比较常用的一种方式。接下来我们来看一下有哪些常用的工具。

Varnishtop

这个工具用于读取共享内存的日志,适当使用一些过滤选项如–I,-i,-X和-x,可以连续不断地显示大部分普通日志。Varnishtop可以按照使用要求显示请求的内容、客户端、浏览器等一些其他日志里的信息。比如:

使用varnishtop -i rxurl查看客户端请求的url次数;

使用Varnishtop -i txurl查看请求后端服务器的url次数;

使用Varnishtop -i Rxheader –I Accept-Encoding查看接收到的头信息中有多少次包含

Accept-Encoding。

Varnishhist

用于读取Varnishd共享内存段的日志,并生成一个连续的柱状图。Varnishhist用于显示最后N个请求的处理情况。如果缓存命中则标记“|”,如果缓存没有命中则标记“#”符号。

Varnishsizes

Varnishsizes和Varnishhist相似,可以查看服务对象的大致大小。

Varnishstat

用于查看Varnish计数丢失率、命中率、存储信息、创建线程、删除对象等。

FAQ

Q:某些HTML页面的http头信息中常带有no-cache头,如何缓存?

A:常规的配置无法实现缓存,需要修改Varnish配置文件,要去掉http头信息中的里no-cache头,修改如下内容:

sub vcl_fetch {

if (req.url ~ ”html$”) {

set beresp.ttl = 10m;

set beresp.do_gzip = true;

unset beresp.http.Cache-Control;

unset beresp.http.Pragma;

set beresp.http.Cache-Control = ”max-age=60″;

unset beresp.http.Expires;

}

}

如果html页面带有cookie,还需要在sub vcl_recv { } 配置中添加如下内容:

sub vcl_recv {

if (req.request == ”GET” && req.url ~ ”\.(js|css|html|jpg|png|gif|swf|jpeg| ico)$”) {

unset req.http.cookie;

}

}

Q:可以在32位机器上运行Varnish吗?

A:可以,不过32位机器不支持大于2GB的文件存储,所以推荐使用64位机器。

Q:Varnish可以做正向代理吗?

A:不可以,Varnish需要配置所有后端服务器到VCL。

Q:怎样做才能在后端服务器记录客户端的IP地址?

A:这是缓存服务器常常遇到的问题。X-Forwarded-For的相关解释已经在前面讲述,只要在后面的Web服务器日志格式中加上相关参数即可。Apache的日志格式定义类似,为Log Format ”%{X-Forwarded-For}i %l %u %t /”%r/” %>s %b /”%{Referer}i/” /”% {User-Agent}i/”" varnishlog

CustomLog /var/log/apache2.log varnishlog

Q:Varnish可以加速https吗?

A:目前还不行,欲知相关信息请密切关注官方网站。

Q:可以查看Varnish缓存了哪些内容吗?

A:目前不可能,如果一个命令列出所有缓存的内容,那么缓存的内容是上千万或者更多,这样会导致因系统资源紧张而使Varnish暂停服务。

varnish 加速相关推荐

  1. 使用Varnish加速Web

    使用Varnish加速Web 1.1 问题 通过配置Varnish缓存服务器,实现如下目标: 使用Varnish加速后端Apache Web服务 使用varnishadm命令管理缓存页面 使用varn ...

  2. CentOS下使用Varnish为网站加速

    1 varnish概述 2 安装varnish 3 varnish 缓存原理 4 实战:缓存一个网站 5 实战:使用varnish缓存多个网站 1 varnish概述 Varnish是一款高性能的开源 ...

  3. 软件加速软件varnish

    --可以参考这个BLOG上的文章 http://ixdba.blog.51cto.com/2895551/682555 http://www.doooor.com/forum.php?mod=view ...

  4. 深入探讨Varnish缓存命中率

    也许你还在为刚才动态内容获得7336.76 reqs/s的吞吐率感到振奋,等等,理想和现实是有差距的,你要忍受现实的残酷,别忘了,我们压力测试中的动态内容都处于全缓存情况下,也就是每次请求都命中缓存, ...

  5. Tomcat服务器 Varnish代理服务器

    Tomcat服务器 概述 Java简介 Java是一种跨平台的,面向对象的程序设计语言,Java技术具有卓越的通用性,高效性,平台移植性和安全性 体系 Java  SE (标准版) Java  EE ...

  6. Varnish缓存代理简介与配置

    一.varnish原理: 1)Varnish简介: varnish缓存是web应用加速器,同时也作为http反向缓存代理.你可以安装varnish在任何http的前端,同时配置它缓存内容.与传统的 s ...

  7. 企业CDN缓存系统varnish——搭建一个最基本的varnish系统

    前面我先给大家讲述一下基本原理和思想,帮助大家彻底理解什么是varnish加速器 虽然互联网企业大多数使用nginx这个功能比较多的服务器,但是单学一个varnish服务器可以让大家彻底理解原理 1. ...

  8. Linux高级运维(十)-搭建企业中最常用缓存代理服务器Squid , Varnish

    搭建varnish 缓存代理服务器 需求: 使用Varnish加速后端Web服务,代理服务器可以将远程的Web服务器页面缓存在本地,远程Web服务器对客户端用户是透明的,利用缓存机制提高网站的响应速度 ...

  9. 秒杀核心设计(减库存部分)-防超卖与高并发

    商品详情页面的静态化,varnish加速,秒杀商品库独立部署服务器这种就略过不讲了.只讨论库存部分的优化 mysql配置层面的优化可以参考我的这篇文章 <关于mysql innodb引擎性能优化 ...

最新文章

  1. 【干货】就这一篇,解决90% 新手连接虚拟机的网络问题
  2. 表的插入、更新、删除、合并操作_13_通过表关联更新多个字段
  3. 中原标准时间对时_GPS对时系统(时间同步系统)应用电子政务
  4. 服务器基线加固脚本_Linux 基线检查,安全加固脚本
  5. 数据库 数据库SQL语句一
  6. vs矩形框边框线显示被选中的区域;_条形码区域解码:Web小工具
  7. 循序渐进学.Net Core Web Api开发系列【7】:项目发布到CentOS7
  8. 原生js代码实现Ajax
  9. 使用微软官方工具MediaCreationTool制作Windows10的U盘系统安装盘
  10. slt mysql_SAP SLT操作手册 PDF 下载
  11. 华为s5700交换机忘记console的密码,怎么恢复
  12. excel箱形图中位数_在Excel中创建简单的箱形图
  13. [渝粤教育] 西北农林科技大学 成本会计学 参考 资料
  14. PHP单例模式(Singleton Pattern)
  15. 7-6 jmu-Java-03面向对象-06-继承覆盖综合练习
  16. 一个软件公司需要多少前端_自己开发一个app需要多少钱,多少时间
  17. 使用Python编写一个倒计时程序
  18. TI DM6437 EDMA3使用总结
  19. mysql单元组多元组_C++11——多元组类别
  20. php 获取pdf 坐标,php – 如何从pdf中提取文本图层和背景图层?

热门文章

  1. 秒杀奥秘——Python实现秒杀某宝商品抢购
  2. 谭维维 鸿蒙音波,揭秘谭维维家庭背景 成长环境竟然是这样的
  3. 一句话解决matlab中plot函数设置坐标轴尺度
  4. ESM(ESModule)和CJS(CommonJS)的区别
  5. Qt如何实现圆角效果
  6. UG二次开发GRIP创建螺牙
  7. Xcode一种涉及到多桌面的调试技巧
  8. C#中调用外部exe的使用、调用powershell、退出进程、委托和事件
  9. 飘雪圣域(icekingdom)
  10. 让你的创业失败的18个昏招