我曾經(jīng)寫過一篇文章──《
初步試用Squid的替代產(chǎn)品──Varnish Cache網(wǎng)站加速器》,但當(dāng)時僅僅是用著玩,沒做深入研究。
今天寫的這篇關(guān)于Varnish的文章,已經(jīng)是一篇可以完全替代Squid做網(wǎng)站緩存加速器的詳細解決方案了。網(wǎng)上關(guān)于Varnish的資料很少,中文資料更是微乎其微,希望本文能夠吸引更多的人研究、使用Varnish。
在我看來,使用Varnish代替Squid的理由有三點: 1、Varnish采用了“Visual Page Cache”技術(shù),在內(nèi)存的利用上,Varnish比Squid具有優(yōu)勢,它避免了Squid頻繁在內(nèi)存、磁盤中交換文件,性能要比Squid高。
2、Varnish的穩(wěn)定性還不錯,我管理的一臺圖片服務(wù)器運行Varnish已經(jīng)有一個月,沒有發(fā)生過故障,而進行相同工作的Squid服務(wù)器就倒過幾次。
3、通過Varnish管理端口,可以使用正則表達式快速、批量地清除部分緩存,這一點是Squid不能具備的。
下面來安裝Varnish網(wǎng)站緩存加速器(Linux系統(tǒng)): 1、創(chuàng)建www用戶和組,以及Varnish緩存文件存放目錄(/var/vcache):
/usr/sbin/groupadd www -g 48
/usr/sbin/useradd -u 48 -g www www
mkdir -p /var/vcache
chmod +w /var/vcache
chown -R www:www /var/vcache
2、創(chuàng)建Varnish日志目錄(/var/logs/):
mkdir -p /var/logs
chmod +w /var/logs
chown -R www:www /var/logs
3、編譯安裝varnish:
4、創(chuàng)建Varnish配置文件:
vi /usr/local/varnish/vcl.conf
輸入以下內(nèi)容:
引用
backend myblogserver {
set backend.host = "192.168.0.5";
set backend.port = "80";
}
acl purge {
"localhost";
"127.0.0.1";
"192.168.1.0"/24;
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
lookup;
}
if (req.http.host ~ "^blog.s135.com") {
set req.backend = myblogserver;
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
else {
lookup;
}
}
else {
error 404 "Zhang Yan Cache Server";
lookup;
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
sub vcl_fetch {
if (req.request == "GET" && req.url ~ "\.(txt|js)$") {
set obj.ttl = 3600s;
}
else {
set obj.ttl = 30d;
}
}
這里,我對這段配置文件解釋一下:
(1)、Varnish通過反向代理請求后端IP為192.168.0.5,端口為80的web服務(wù)器;
(2)、Varnish允許localhost、127.0.0.1、192.168.0.***三個來源IP通過PURGE方法清除緩存;
(3)、Varnish對域名為blog.s135.com的請求進行處理,非blog.s135.com域名的請求則返回“Zhang Yan Cache Server”;
(4)、Varnish對HTTP協(xié)議中的GET、HEAD請求進行緩存,對POST請求透過,讓其直接訪問后端Web服務(wù)器。之所以這樣配置,是因為POST請求一般是發(fā)送數(shù)據(jù)給服務(wù)器的,需要服務(wù)器接收、處理,所以不緩存;
(5)、Varnish對以.txt和.js結(jié)尾的URL緩存時間設(shè)置1小時,對其他的URL緩存時間設(shè)置為30天。
5、啟動Varnish
ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on
6、啟動varnishncsa用來將Varnish訪問日志寫入日志文件:
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/varnish.log &
7、配置開機自動啟動Varnish
vi /etc/rc.local
在末尾增加以下內(nèi)容:
引用
ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/youvideo.log &
8、優(yōu)化Linux內(nèi)核參數(shù)
vi /etc/sysctl.conf
在末尾增加以下內(nèi)容:
引用
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000
再看看如何管理Varnish: 1、查看Varnish服務(wù)器連接數(shù)與命中率:
/usr/local/varnish/bin/varnishstat
2、通過Varnish管理端口進行管理:
用help看看可以使用哪些Varnish命令:
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 help
引用
Available commands:
ping [timestamp]
status
start
stop
stats
vcl.load
vcl.inline
vcl.use
vcl.discard
vcl.list
vcl.show
param.show [-l] []
param.set
help [command]
url.purge
dump.pool
3、通過Varnish管理端口,使用正則表達式批量清除緩存:
(1)、例:清除類似
http://blog.s135.com/a/zhangyan.html的URL地址):
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge /a/
(2)、例:清除類似
http://blog.s135.com/tech的URL地址:
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge w*$
(3)、例:清除所有緩存:
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge *$
4、一個清除Squid緩存的PHP函數(shù)(清除Varnish緩存同樣可以使用該函數(shù),無需作任何修改,十分方便):
- <?php
- function purge($ip, $url)
- {
- $errstr = '';
- $errno = '';
- $fp = fsockopen ($ip, 80, $errno, $errstr, 2);
- if (!$fp)
- {
- return false;
- }
- else
- {
- $out = "PURGE $url HTTP/1.1\r\n";
- $out .= "Host:blog.s135.com\r\n";
- $out .= "Connection: close\r\n\r\n";
- fputs ($fp, $out);
- $out = fgets($fp , 4096);
- fclose ($fp);
- return true;
- }
- }
-
- purge("192.168.0.4", "/index.php");
- ?>
附1:Varnish官方網(wǎng)站:
http://www.varnish-cache.org/ 附2:2007年12月10日,我寫了一個每天0點運行,按天切割Varnish日志,生成一個壓縮文件,同時刪除上個月舊日志的腳本(/var/logs/cutlog.sh):
/var/logs/cutlog.sh文件內(nèi)容如下:
引用
#!/bin/sh
# This file run at 00:00
date=$(date -d "yesterday" +"%Y-%m-%d")
pkill -9 varnishncsa
mv /var/logs/youvideo.log /var/logs/${date}.log
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/logs/youvideo.log &
mkdir -p /var/logs/youvideo/
gzip -c /var/logs/${date}.log > /var/logs/youvideo/${date}.log.gz
rm -f /var/logs/${date}.log
rm -f /var/logs/youvideo/$(date -d "-1 month" +"%Y-%m*").log.gz
設(shè)置在每天00:00定時執(zhí)行:
/usr/bin/crontab -e
或者
vi /var/spool/cron/root
輸入以下內(nèi)容:
引用
0 0 * * * /bin/sh /var/logs/cutlog.sh
varnish如何做到在不重啟的情況下重新載入配置文件
用varnish做反向代理的時候,登錄一般的網(wǎng)站沒有任何問題。登錄DZ論壇的后臺出現(xiàn)無法登錄,沒有任何提示。用squid就沒有這樣的問題,不知道那位老大遇到過這樣的問題。
張宴 回復(fù)于 2007-12-5 19:08
出問題是肯定的,因為本文中的Varnish配置將緩存所有類型的文件,而你使用squid之所以正常,是因為在squid配置文件中沒有配置去緩存php文件。同樣,對于Varnish,你可以選擇不緩存.php文件,修改vcl.conf配置文件:
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
elseif(req.url ~ "\.(php|cgi)($|\?)") {
pass;
}
else {
lookup;
}
張兄,今天測了一下varnish,原來用nginx+squid ESTAB連接大概在1700的機器換了varnish后連接數(shù)只有300多了,訪問起來一切正常,cacti查看到流量也是正常的,難道varnish就強在這
?配置是按您的配置做的。
另外還有個問題vcache這個目錄是用來保存cache文件的是嗎?我在ll vcache里什么文件都沒有。
還有用varnish這個方法還解決了一直讓我頭疼的squid不支持iis compress問題,實在太感謝了
張宴 回復(fù)于 2007-12-5 20:02
TCP連接數(shù)Varnish要比Squid少,因為Varnish的TCP連接釋放要比Squid快。
但同時處理的請求數(shù)Varnish要比Squid高一些,這是我在F5 BIG-IP下的兩臺服務(wù)器,一臺Varnish、另一臺Squid,F(xiàn)5 BIG-IP分給它們的連接數(shù)相同,Varnish實時處理的請求數(shù)比Squid多1倍,平均處理的請求數(shù)也比Squid多100余個:
/usr/local/webserver/varnish/bin/varnishstat
-----------------------------------------------------------
70979868 580.97 356.55 Client requests received
70897998 580.97 356.14 Cache hits
/usr/local/squid/bin/squidclient -p 80 mgr:5min
-----------------------------------------------------------
client_http.requests = 248.425264/sec
client_http.hits = 245.135282/sec
如果正常的話,vcache這個目錄里只有一個大小為1G的文件:varnish_cache.data
今天遇到的問題貌似跟樓上說的一樣,varnish做反向代理后dvbbs登陸不正常,用戶登陸后顯示同一個用戶名,驗證碼不變。
張宴 回復(fù)于 2007-12-5 19:21
正好這兩天我在自己的BLOG上也做了varnish緩存的實驗
用varnishncsa輸出日志,但發(fā)現(xiàn)里面有不少日志條目是127.0.0.1來的訪問,覺得比較奇怪,是不是varnishd工作時候產(chǎn)生的?上網(wǎng)找也沒找到相關(guān)的解釋。
老大你有沒有相關(guān)知識分享一下?嘿嘿
discuz 做緩存的話 ,可以試試使用緩存帖子分頁。
varnish可以實現(xiàn)類似于squid那樣的父子節(jié)點關(guān)系嗎?
今天在另外一個平臺上使用varnish測試
增加了
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
elseif(req.url ~ "\.(aspx|asp|shtml|vimg)($|\?)") {
pass;
}
else {
lookup;
}
}
后還是偶爾有用戶登陸后顯示別人的用戶名
而且程序員更新js文件后不能馬上看到
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge *$
purge所有后也不行,還發(fā)現(xiàn)一個小問題執(zhí)行 varnishadm后容易使varnishd父進程吃cpu 100%一直下不來
我的訪問量在 350 request/sec
e文的理解能力比較查在man跟官方faq里似乎沒看到類似情況
緩存不該緩存的對象的問題
也許可以通過在recv里
if (req.http.Cache-Control ~ "no-cache") {
pass;
}
在fetch里加
if (obj.http.Pragma ~ "no-cache" || obj.http.Cache-Control ~ "no-cache" || obj.http.Cache-Control ~ "private") {
pass;
}
ping [timestamp]
status
start
stop
stats
vcl.load <configname> <filename>
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname>
vcl.discard <configname>
vcl.list
vcl.show <configname>
param.show [-l] [<param>]
param.set <param> <value>
help [command]
telnet 管理有個 vcl.load 應(yīng)該可以 不重啟的情況下重新載入配置文件
張老師,我裝好了,一切正常,只提到的管理這些功能不正常:
[root@linux1 ~]# /usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500
usage: varnishadm -T [address]:port command [...]
上面命令明明沒有問題,端口監(jiān)聽也正常.
[root@linux1 ~]# /usr/local/varnish/bin/varnishstat
Cannot open /usr/local/varnish/var/varnish/www.38hao.org/_.vsl: No such file or directory
但是我的,這_.vsl文件明明是在/data/cache目錄下,他非到 /usr/local/varnish/var/varnish/下讀!
張宴 回復(fù)于 2007-12-20 21:31
/usr/local/varnish/bin/varnishstat -n /data/vcache
[root@localhost root]# cat start_cache.sh
ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /home/cache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:81 -s file,/home/cache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on
/usr/local/varnish/bin/varnishncsa -n /home/cache -w /home/logs/www.log &
[root@localhost root]# sh start_cache.sh
file /home/cache/varnish_cache.data size 1073741824 bytes (262144 fs-blocks, 262144 pages)
Using old SHMFILE
[root@localhost root]# netstat -untl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:199 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
udp 0 0 0.0.0.0:161 0.0.0.0:*
服務(wù)啟動時也不報錯,就是看不到varnish監(jiān)聽的端口,如何debug? 實在看不出什么問題,
請張老師指點一下!
(1)、Varnish通過反向代理請求后端IP為192.168.0.5,端口為80的web服務(wù)器;
backend.host 如果有多臺的話 是否也可以象 SQUID 那樣設(shè)置在 hosts文件里面,
(3)、Varnish對域名為blog.s135.com的請求進行處理,非blog.s135.com域名的請求則返回“Zhang Yan Cache Server”;
squid 可以根據(jù)到目的IP是否符合在判斷是否可以使用 這樣就不用判斷域名 不知道在 Varnish 也可以這樣設(shè)置
張老師,我服務(wù)器上用varnish+nginx在同一臺機器上跑,運行沒有三分鐘的時候,就開始卡,仍后幾乎網(wǎng)頁打不開。不知道什么原因,而我在本地虛擬環(huán)境測試一點問題都沒有,只是本地的是varnish+apache,而線上服務(wù)器是varnish+nginx,有點不解,請張老師指點一下,有遇到想關(guān)問題的朋友指點一下!
原來本地是squid+nginx速度飛快,現(xiàn)在是varnish+nginx就卡得不行...
問下varnish 怎么配置 泛域名 的主機,我很很多二級域名,比如 xx.abc.com ,一個一個加好麻煩。。。squid 或者nginx 都支持 .abc.com 的
張宴 回復(fù)于 2008-1-4 21:24
if (req.http.host ~ "^blog.s135.com") {
改成
if (req.http.host ~ ".abc.com") {
antiaiqingno
2008-1-6 16:56
需要反向DNS
問個問題,如果要做個全國性的網(wǎng)站負載均衡,可否搭配varnish+F5 bigip實現(xiàn)
1.varnish專門做cache Server
2.F5 Bigip用做服務(wù)器負載均衡
張宴 回復(fù)于 2008-1-7 08:16
F5 BIGIP + Varnish是可行的,但是Varnish的緩存基本上在內(nèi)存中,如果Varnish進程停止再啟動,Varnish就會重新訪問后端Web服務(wù)器。
還有種方案就是F5 BIGIP + Squid,Squid的緩存會保持在磁盤和內(nèi)存,雖然Squid性能沒有Varnish高,但它停止、重啟的時候,可以直接先從磁盤讀取緩存數(shù)據(jù)。
引用
F5 BIGIP + Varnish是可行的,但是Varnish的緩存基本上在內(nèi)存中,如果Varnish進程停止再啟動,Varnish就會重新訪問后端Web服務(wù)器。
還有種方案就是F5 BIGIP + Squid,Squid的緩存會保持在磁盤和內(nèi)存,雖然Squid性能沒有Varnish高,但它停止、重啟的時候,可以直接先從磁盤讀取緩存數(shù)據(jù)。
這樣的話.重啟Varnish會導(dǎo)致邊緣節(jié)點訪問一定時間內(nèi)卡一下吧?
內(nèi)存方式雖然快.但是這點上會很郁悶了.
張老師:我出現(xiàn)如下錯誤
101 32
all commands are in lower-case.
我的配置是這樣的 Varnish 和 nginx 同在一臺機器上,沒辦法,只有一臺機器。我把Varnish配置為公網(wǎng)的80,如 210.21.21.21:80 這樣,nginx配置為:127.0.0.1:80 啟動是正常的,但訪問時出現(xiàn)
101 32
all commands are in lower-case.