Varnish是一款高性能且开源的反向代理服务器和http加速器。与传统的Squid相比,Varnish具有性能更高、速度更快、管理更方便 等诸多优点。作者Poul-Henning Kamp是FreeBSD的内核开发者之一。Varnish采用全新的软件体系架构,和现在的硬件提交配合紧密。在1975年时,储存媒介只有两种:内存 与硬盘。但现在计算 机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构。

挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前更好,这是Varnish最成功的应用案例。

Varnish特点:

  • 基于内存进行缓存,重启后数据将消失
  • 利用虚拟内存方式,I/O性能好
  • 支持设置0~60秒的精确缓存时间
  • VCL配置管理比较灵活
  • 32位机器上缓存文件大小最大为2G
  • 具有强大的管理功能,例如top、stat、admin、list等
  • 状态机设置巧妙,结构清晰
  • 利用二叉堆管理缓存文件,可达到积极删除目的

Varnish与Squid的对比
Squid是一个高性能的代理缓存服务器,它和varnish之间有诸多的异同点,如下:
相同点:

  1. 都是一个反向代理服务器
  2. 都是开源软件

不同点,也是Varnish的优点:

  1. Varnish的稳定性很高,两者在完成相同负荷的工作时,Squid服务器发生故障的几率要高于Varnish,因为使用Squid要经常重启。
  2. Varnish访问速度更快,Varnish采用了“Visual Page Cache”技术,所有缓存数据都直接从内存读取,而squid是从硬盘读取,因而Varnish在访问速度方面会更快。
  3. Varnish可以支持更多的并发连接,因为Varnish的TCP连接释放要比Squid快。因而在高并发连接情况下可以支持更多TCP连接。
  4. Varnish可以通过管理端口,使用正则表达式批量的清除部分缓存,而Squid是做不到的。
  5. squid属于是单进程使用单核CPU,但Varnish是通过fork形式打开多进程来做处理,所以是合理的使用所有核来处理相应的请求。

当然,与传统的Squid相比,Varnish也是有缺点的,如下:

  1. varnish进程一旦挂起、崩溃或者重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力。
  2. 在varnish使用中如果单个url的请求通过HA/F5(负载均衡)每次请求不同的varnish服务器中,被请求varnish服务器都会被穿透到后端,而且同样的请求会在多台服务器上缓存,也会造成varnish的缓存的资源浪费,也会造成性能下降。

解决方案:

  1. 综上所述在访问量很大的情况下推荐使用varnish的内存缓存方式启动,而且后面需要跟多台squid服务器。主要为了防止前面的varnish服务、
    服务器被重启的情况下,前期肯定会有很多的穿透这样squid可以担当第二层cache,而且也弥补了varnish缓存在内存中重启都会释放的问题。
  2. 这样的问题可以在负载均衡上做url哈希,让单个url请求固定请求到一台varnish服务器上,可以解决该问题。

varnish的工作流程
1、进程之间通信
varnish启动或有2个进程
master(management)进程和child(worker)进程。master读入存储配置命令,进行初始化,然后fork,监控
child。child则分配线程进行cache工作,child还会做管理线程和生成很多worker线程。

child进程主线程初始化过程中,将存储大文件整个加载到内存中,如果该文件超出系统的虚拟内存,则会减少原来配置mmap大小,然后继续加载,这时候创建并初始化空闲存储结构体,放在存储管理的struct中,等待分配。

接着varnish某个负责接口新http连接的线程开始等待用户,如果有新的http连接,但是这个线程只负责接收,然后唤醒等待线程池中的work线程,进行请求处理。

worker线程读入uri后,将会查找已有的object,命中直接返回,没有命中,则会从后端服务器中取出来,放到缓存中。如果缓存已满,会根
据LRU算法,释放旧的object。对于释放缓存,有一个超时线程会检测缓存中所有object的生命周期,如果缓存过期(ttl),则删除,释放相应
的存储内存。

2、配置文件各结构之间通信

Varnish安装

wget http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-8.33.tar.gz
tar xzf pcre-8.33.tar.gz
cd pcre-8.33./configure
make && make install
cd ../

varnish-3.0.4报错如下:

varnishadm.c:48:33: error: editline/readline.h:No such file or directory
varnishadm.c:Infunction'cli_write':
varnishadm.c:76: warning: implicit declaration of function'rl_callback_handler_remove'
varnishadm.c:76: warning: nested extern declaration of 'rl_callback_handler_remove'
varnishadm.c:Infunction'send_line':
varnishadm.c:179: warning: implicit declaration of function'add_history'
varnishadm.c:179: warning: nested extern declaration of 'add_history'
varnishadm.c:Infunction'varnishadm_completion':
varnishadm.c:216: warning: implicit declaration of function'rl_completion_matches'
varnishadm.c:216: warning: nested extern declaration of 'rl_completion_matches'
varnishadm.c:216: warning: assignment makes pointer from integer without a cast
varnishadm.c:Infunction'pass':
varnishadm.c:233: error:'rl_already_prompted' undeclared (first use in this function)
varnishadm.c:233: error:(Each undeclared identifier is reported only once
varnishadm.c:233: error:for each function it appears in.)
varnishadm.c:235: warning: implicit declaration of function'rl_callback_handler_install'
varnishadm.c:235: warning: nested extern declaration of 'rl_callback_handler_install'
varnishadm.c:239: error:'rl_attempted_completion_function' undeclared (first use in this function)
varnishadm.c:300: warning: implicit declaration of function'rl_forced_update_display'
varnishadm.c:300: warning: nested extern declaration of 'rl_forced_update_display'
varnishadm.c:303: warning: implicit declaration of function'rl_callback_read_char'
varnishadm.c:303: warning: nested extern declaration of 'rl_callback_read_char'
make[3]:***[varnishadm-varnishadm.o]Error1
make[3]:Leaving directory `/root/lnmp/src/varnish-3.0.4/bin/varnishadm'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/root/lnmp/src/varnish-3.0.4/bin'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/lnmp/src/varnish-3.0.4'
make:***[all]Error2

报错没找到解决方法,选varnish-3.0.3

wget http://repo.varnish-cache.org/source/varnish-3.0.3.tar.gz
tar xzf varnish-3.0.3.tar.gz
cd varnish-3.0.3
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
./configure --prefix=/usr/local/varnish --enable-debugging-symbols --enable-developer-warnings --enable-dependency-tracking --with-jemalloc
make && make install
/usr/bin/install -m 755./redhat/varnish.initrc /etc/init.d/varnish
/usr/bin/install -m 644./redhat/varnish.sysconfig /etc/sysconfig/varnish
/usr/bin/install -m 755./redhat/varnish_reload_vcl /usr/local/varnish/bin
useradd -M -s /sbin/nologin varnish ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/
ln -s /usr/local/varnish/bin/varnish_reload_vcl /usr/bin/
ln -s /usr/local/varnish/bin/varnishadm /usr/bin/ chkconfig --add varnish
chkconfig varnish on

生成varnish管理秘钥:

uuidgen >/usr/local/varnish/etc/varnish/secret
chmod 644/usr/local/varnish/etc/varnish/secret

修改varnish启动配置:

sed -i "s@^VARNISH_VCL_CONF=/etc/varnish/default.vcl@#VARNISH_VCL_CONF=/etc/varnish/default.vcl\nVARNISH_VCL_CONF=/usr/local/varnish/etc/varnish/linuxeye.vcl@"/etc/sysconfig/varnish
sed -i "s@^VARNISH_LISTEN_PORT=6081@#VARNISH_LISTEN_PORT=6081\nVARNISH_LISTEN_PORT=80@"/etc/sysconfig/varnish
sed -i "s@^VARNISH_SECRET_FILE=/etc/varnish/secret@#VARNISH_SECRET_FILE=/etc/varnish/secret\nVARNISH_SECRET_FILE=/usr/local/varnish/etc/varnish/secret@"/etc/sysconfig/varnish
sed -i "s@^VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin@#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin\nVARNISH_STORAGE_FILE=/usr/local/varnish/var/varnish_storage.bin@"/etc/sysconfig/varnish
sed -i "s@^VARNISH_STORAGE_SIZE.*@VARNISH_STORAGE_SIZE=150M@"/etc/sysconfig/varnish
sed -i "s@^VARNISH_STORAGE=.*@VARNISH_STORAGE=\"malloc,\${VARNISH_STORAGE_SIZE}\"@"/etc/sysconfig/varnish

假设你的服务器拥有多颗逻辑处理器,还可以做以下的设置:
/etc/sysconfig/varnish 里面还可以添加自定义的参数,用”-p 参数“的方式添加,如:

DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-t ${VARNISH_TTL} \
-w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
-u varnish -g varnish \
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE} \
-p thread_pools=2"#这里为添加项

Varnish启动后进入后台运行,同时返回命令行状态。需要注意的是,Varnish运行时会同时启动两个进程,一个主进程,一个是子进程,如果子进程出现问题,主进程将重新生成一个子进程。

VCL配置
/usr/local/varnish/etc/varnish/linuxeye.vcl.sh

#通过backend定义了一个名称为webserver的后端主机,“.host”指定后端主机的IP地址或者域名,“.port”指定后端主机的服务端口。
backend webserver {.host ="127.0.0.1";.port ="8080";}#调用vcl_recv开始
sub vcl_recv {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;}}#如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,进入pipe模式。注意这里是“&&”的关系
 if(req.request !="GET"&&
req.request !="HEAD"&&
req.request !="PUT"&&
req.request !="POST"&&
req.request !="TRACE"&&
req.request !="OPTIONS"&&
req.request !="DELETE"){return(pipe);}#如果请求的类型不是GET与HEAD,则进入pass模式
  if(req.request !="GET"&& req.request !="HEAD"){return(pass);}if(req.http.Authorization|| req.http.Cookie){return(pass);}#对linuxeye.com域名进行缓存加速,这是个泛域名的概念,也就是所有以linuxeye.com结尾的域名都进行缓存
  if(req.http.host ~"^(.*).linuxeye.com"){set req.backend = webserver;}#对以.jsp、.do、php结尾以及带有?的URL时,直接从后端服务器读取内容
  if(req.url ~"\.(jsp|do|php)($|\?)"){return(pass);}else{return(lookup);}} sub vcl_pipe {return(pipe);} sub vcl_pass {return(pass);} sub vcl_hash {
hash_data(req.url);if(req.http.host){
hash_data(req.http.host);}else{
hash_data(server.ip);}return(hash);} sub vcl_hit {return(deliver);} sub vcl_miss {return(fetch);}#对于请求类型是GET,并且请求的URL中包含upload,那么就进行缓存,缓存的时间是300秒,即5分钟
sub vcl_fetch {if(req.request =="GET"&& req.url ~"^/upload(.*)$"){set beresp.ttl =300s;}if(req.request =="GET"&& req.url ~"\.(png|gif|jpg|jpeg|bmp|swf|css|js|html|htm|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|txt)$"){
unset beresp.http.set-cookie;set beresp.ttl =30d;}return(deliver);}#下面是添加一个Header标识,以判断缓存是否命中
sub vcl_deliver {if(obj.hits >0){set resp.http.X-Cache="HIT from demo.linuxeye.com";}else{set resp.http.X-Cache="MISS from demo.linuxeye.com";}return(deliver);}#使用vcl_error可以定制一个错误页面
sub vcl_error {set obj.http.Content-Type="text/html; charset=utf-8";set obj.http.Retry-After="5";
synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Strict//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>
<p>Varnish cache server</p>
</body>
</html>
"};return(deliver);} sub vcl_init {return(ok);} sub vcl_fini {return(ok);}

检查VCL配置是否正确:

service varnish configtest

varnishd -C -f /usr/local/varnish/etc/varnish/linuxeye.vcl

启动varnish:

service varnish start

查看varnish状态:

service varnish status

动态加载VCL配置:

service varnish reload

停止varnish:

service varnish stop

查看当前varnish监听的80端口:

# netstat -tpln | grep :80
tcp 000.0.0.0:800.0.0.0:* LISTEN 15249/varnishd
tcp 000.0.0.0:80800.0.0.0:* LISTEN 19468/nginx
tcp 00:::80:::* LISTEN 15249/varnishd

查看varnish进程:

# ps -ef | grep varnishd | grep -v grep
root 152481011:47?00:00:00/usr/sbin/varnishd -P /var/run/varnish.pid -a :80-f /usr/local/varnish/etc/varnish/linuxeye.vcl -T 127.0.0.1:6082-t 120-w 50,1000,120-u varnish -g varnish -S /usr/local/varnish/etc/varnish/secret -s malloc,150M
varnish 1524915248011:47?00:00:00/usr/sbin/varnishd -P /var/run/varnish.pid -a :80-f /usr/local/varnish/etc/varnish/linuxeye.vcl -T 127.0.0.1:6082-t 120-w 50,1000,120-u varnish -g varnish -S /usr/local/varnish/etc/varnish/secret -s malloc,150M

Varnish访问日志
varnishncsa可以使用NCSA通用日志格式(NCSA Common Log Format)将HTTP请求记录到日志文件.

/usr/bin/install -m 755./redhat/varnishncsa.initrc /etc/init.d/varnishncsa
chmod +x /etc/init.d/varnishncsa
chkconfig varnishncsa on
mkdir -p /usr/local/varnish/logs

编辑varnishncsa启动配置

ln -s /usr/local/varnish/bin/varnishncsa /usr/bin
sed -i 's@^logfile.*@logfile="/usr/local/varnish/logs/varnishncsa.log"@'/etc/init.d/varnishncsa

启动varnishncsa:

service varnishncsa start

使用logrotate轮询日志文件(每天轮询):

cat >/etc/logrotate.d/varnish << EOF
/usr/local/varnish/logs/varnishncsa.log {
daily
rotate 5
missingok
dateext
compress
notifempty
sharedscripts
postrotate
[-e /var/run/varnishncsa.pid ]&& kill -USR1 \`cat /var/run/varnishncsa.pid\`
endscript
}
EOF

日志轮询debug测试:

logrotate -df /etc/logrotate.d/varnish

个人博客:http://blog.linuxeye.com/360.html

Varnish – 高性能http加速器的更多相关文章

  1. 高性能HTTP加速器Varnish安装与配置(包含常见错误)

    Varnish是一款高性能的开源HTTP加速器.挪威最大的在线报纸Verdens Gang使用3台Varnish取代了原来的12台Squid,性能竟然比曾经更好.Varnish 的作者Poul-Hen ...

  2. 高性能HTTP加速器Varnish安装与配置

    导读 Varnish是一款高性能且开源的反向代理服务器和HTTP加速器,它采用了全新的软件体系结构,和现在的硬件体系配合紧密.下面就由我给大家简单说说他的安装与配置. 安装 安装pcre 如果没有安装 ...

  3. 高性能HTTP加速器Varnish--基础知识

    一.Varnish 概述 Varnish 是一款高性能且开源的反向代理服务器和HTTP加速器,它的开发者 Poul-Henning Kamp 是 FreeBSD 核心的开发人员之一. 与传统的 Squ ...

  4. Linux平台部署varnish 高性能缓存服务器

    一:varnish部署前准备: 1.1相关软件以及系统,web服务 系统要求:Centos 6(以上) (64位) 相关中间件:varnish-4.0.2 1.2相关系统依赖包安装检查准备 1.2.1 ...

  5. 高性能HTTP加速器Varnish-3.0.3搭建、配置及优化步骤

    经过一天的努力,终于将Varnish缓存服务器部署到线上服务器了.趁着热乎劲儿,赶紧给大家分享一下.Varnish是一个轻量级的Cache和反向代理软件.先进的设计理念和成熟的设计框架是Varnish ...

  6. 《大规模web服务开发技术》笔记

    前段时间趁空把<大规模web服务开发技术>这本书看完了,今天用一下午时间重新翻了一遍,把其中的要点记了下来,权当复习和备忘.由于自己对数据压缩.全文检索等还算比较熟,所以笔记内容主要涉及前 ...

  7. 使用Varnish代替Squid做网站缓存加速器的详细解决方案----转载

    [文章作者:张宴 本文版本:v1.2 最后修改:2008.01.02 转载请注明出处:http://blog.s135.com] 我曾经写过一篇文章──<初步试用Squid的替代产品──Varn ...

  8. Web缓存(Varnish方案)

    Web缓存(Varnish方案) 转载 http://www.s135.com/post/313/ arnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (htt ...

  9. Varnish 学习资料收集

    高性能HTTP加速器Varnish(安装配置篇) 利用Varnish构建Cache服务器笔记 Varnish代理服务器部署 Varnish基础概念详解 Varnish的配置语言VCL及其内置变量介绍 ...

随机推荐

  1. OpenCV在Android平台上的应用

    今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...

  2. HDU 4604 deque 最长上升子序列

    枚举每个位置,求以num[i]为起点的最长不下降子序列和以num[i]为结尾的最长不递增子序列. 并且把相同值的个数统计一下,最后要减去算重复了的. 比如: 1 9 4 4 2 2 2 3 3 3 7 ...

  3. 10位顶级PHP大师的开发原则

    在Web开发世界里,PHP是最流行的语言之一,从PHP里,你能够很容易的找到你所需的脚本,遗憾的是,很少人会去用“最佳做法”去写一个PHP程序.这里,我们向大家介绍PHP的10种最佳实践,当然,每一种 ...

  4. Zookeeper集群和HBase集群

    1.部署Zookeeper集群(hadoop0\hadoop1\hadoop2) 1.1.在hadoop0上解压缩Zookeeper-3.4.5.tar.gz 1.2.执行命令 cp conf/zoo ...

  5. sendmessage()模拟鼠标点击

    {鼠标软模拟:好处就是不会真的移动鼠标 开始按钮 坐标 x=386y=387 }sendmessage(hookHwnd,messages.WM_LBUTTONDOWN ,0,$0180017A); ...

  6. ScaleGestureDetector缩放view

    public class ScaleGesture implements OnScaleGestureListener { private float beforeFactor; private fl ...

  7. android截屏:保存一个view的内容为图片并存放到SD卡

    项目中偶尔会用到截屏分享,于是就有了下面这个截屏的方法~ 下面得saveImage()方法就是保存当前Activity对应的屏幕所有内容的截屏保存. private void saveImage() ...

  8. BZOJ2226: [Spoj 5971] LCMSum

    题解: 考虑枚举gcd,然后问题转化为求<=n且与n互质的数的和. 这是有公式的f[i]=phi[i]*i/2 然后卡一卡时就可以过了. 代码: #include<cstdio> # ...

  9. H264码流打包分析(精华)

    H264码流打包分析 SODB 数据比特串-->最原始的编码数据 RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若 ...

  10. windows下MySql没有setup.exe时的安装方法

    01.把 mysql-advanced-5.6.17-winx64.zip 解压到自定义 D:\mysql-5.6.17-W64 或 D:\mysql-advanced-5.6.17-winx64 目 ...