Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前更好。
Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算 机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构。
具体安装方法
安装 CentOS 5.x 的Varnish RPM仓库
rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release/varnish-release-3.0-1.el5.centos.noarch.rpm
安装 CentOS 6.x 的Varnish RPM仓库
rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm
然后执行安装完毕
yum install varnish
修改启动参数:
vim /etc/sysconfig/varnish
默认HTTP端口:6081
默认管理端口:6082
默认缓存模式为file:file,/var/lib/varnish/varnish_storage.bin,1G
共三种模式file, malloc, persistent
(1)file:使用特定的文件存储全部的缓存数据,并通过操作系统的mmap()系统调用将整个缓存文件映射至内存区域(如果条件允许);
(2)malloc:使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象;
(3)persistent(experimental):与file的功能相同,但可以持久存储数据(即重启varnish数据时不会被清除);仍处于测试期;
修改varnish配置文件
vim /etc/varnish/default.vcl
VCL配置
############定义健康状态检测###############
probe healthcheck {
.url = "/"; #定义健康检查的页面
.interval = 6s; #探测请求的发送周期,默认为5秒;
.timeout = 1s; #每次探测请求的过期时长
.window = 8; #设定在判定后端主机健康状态时基于最近多少次的探测进行
.threshold = 3; #在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行
.initial = 3; #Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold
}
############## app 服务器组及集群策略 ################
backend app01 {
.host = "192.168.0.5";
.port = "80";
.probe = healthcheck; #健康状态检测
}
backend app02 {
.host = "192.168.0.6";
.port = "80";
.probe = healthcheck; #健康状态检测
}
# 定义集群,调用服务器
director app random { #定义一个名为webserver的directory,由app01,app02,使用random算法,处理静态请求
{.backend = app01;.weight = 5;} #设置权重为
{.backend = app02;.weight = 5;}
}
############## img 服务器 ################
backend img {
.host = "192.168.0.1";
.port = "80";
}
#######################################
#purge的acl规则
acl purge {
"localhost";
"127.0.0.1";
}
#vcl_recv函数段
sub vcl_recv
{
# varnish内部有一个grace模式。当后端不可用,或者已经向后端发过更新请求的情况下,别的客户再请求这个对象时,会收到已经过期的版本,当然过期的时间在可接受的范围内。
# 在收到用户请求时指定可以接受过期对象的过期时间范围
if (!req.backend.healthy) {
set req.grace = 5m;
} else {
set req.grace = 15s;
}
#定义清除缓存IP,调用上面的Acl
if (req.request == "PURGE") { #使用PURGE命令清除缓存
if (!client.ip ~ purge) { #非ACl定义的IP,则不能清除缓存
error 405 "Not allowed.";
}
return (lookup);
}
if (req.restarts == 0) {
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.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# 对图片及压缩文件的 Accept-Encoding 统一化 提高命中率
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
# No point in compressing these
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unknown algorithm
unset req.http.Accept-Encoding;
}
}
############# 自定义主机规则开始 ############
if (req.url ~ "^http://") {
set req.url = regsub(req.url, "http://[^/]*", "");
}
if (req.http.host ~ "^img.test.com")
{
# 删除COOKIE 提高命中
# unset req.http.Cookie;
set req.backend = img;
}
elseif (req.http.host ~ "^www.test.com")
{
set req.backend = app;
}
else
{
error 200 "Unknown virtual host";
}
# 扩展名为 php|cgi|asp|jsp|do|aspx 脚本的不缓存
if (req.url ~ "\.(php|cgi|asp|jsp|do|aspx)($|\?)")
{
return (pass);
}
############# 自定义主机规则结束 ############
# 不缓存GET或HEAD以外的请求
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
# 不缓存验证信息和Cookie
if (req.http.Authorization || req.http.Cookie) {
return (pass);
}
# 所有缓存控制为 no-cache 的不缓存
if (req.http.Cache-Control ~ "no-cache") {
return (pass);
}
return (lookup);
}
sub vcl_hit
{
if (req.request == "PURGE")
{
set obj.ttl = 0s;
error 200 "Purged.";
}
return (deliver);
}
sub vcl_miss
{
if (req.request == "PURGE")
{
error 404 "Not in cache.";
}
}
sub vcl_fetch
{
# 设定默认缓存时长
set beresp.ttl = 300s; #超时时长为300秒
# 定义缓存时长
if (req.url ~ "\.(css|js|html|htm|xsl|xml)$") {
set beresp.ttl = 300s; #超时时长为300秒
}
# 图片/视频/音频/文档/压缩文件 缓存时常
if (req.url ~ "\.(png|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg)$") {
set beresp.http.Pragma = "cache";
set beresp.http.Cache-Control = "max-age=31536000, public";
set beresp.ttl = 365d;
}
# 如果后端状态为 404 则缓存 600s
if(beresp.status == 400 && beresp.status == 403 && beresp.status == 404) {
set beresp.ttl = 600s;
}
# 如果后端服务器出现 500/501/502/503/504 错误时进入神圣模式 saintmode
if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
set beresp.saintmode = 20s;
return (restart);
}
# grace时长,减少高并发下的穿透和争抢,设置缓存对象过期后还可以保留的时间
set beresp.grace = 5m;
return (deliver);
}
# 交付页面
sub vcl_deliver
{
if (obj.hits > 0)
{
set resp.http.X-Cache = "HIT";
}
else
{
set resp.http.X-Cache = "MISS";
}
#去掉 varnish 中的一些头信息(如果你不想保留的话,建议保留 Age,方便查看)
unset resp.http.X-Varnish;
unset resp.http.Via;
return (deliver);
}
# 自定义错误页面信息
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>
<p style='font-family:Tahoma; font-size:14px;'>
<b>Status</b>: "} + obj.status + {"<br>
<b>Info</b>: "} + obj.response + {"<br>
<b>XID</b>: "} + req.xid + {"<br></p>
</body>
</html>
"};
return (deliver);
}
启动服务
Usage: /etc/init.d/varnish {start|stop|status|restart|condrestart|try-restart|reload|force-reload}
service varnish start
中文资料:
更多配置可参考:http://my.oschina.net/jean/blog/189916
更多理论知识:http://my.oschina.net/jean/blog/189910
Varnish缓存策略及缓存时间计算方法说明:http://my.oschina.net/jean/blog/189908
Varnish3.0中文入门教程:http://anykoro.sinaapp.com/2012/01/31/varnish3-0中文入门教程
Varnish调优手记:http://my.oschina.net/u/572653/blog/178201
英文资料:
Varnish官方文档:
https://www.varnish-cache.org/docs/3.0/index.html
PHP的Varnish扩展,主要功能VarnishAdmin VarnishStat VarnishLog
http://www.php.net/manual/zh/book.varnish.php
用 Varnish 扩展 PHP 应用程序
http://www.ibm.com/developerworks/cn/opensource/os-php-varnish/
来源:oschina
链接:https://my.oschina.net/u/97799/blog/189869