簡介:
Varnish是一款高性能、開源的反向代理伺服器和緩存伺服器,官方說是squid的四倍,實際應用測試中雖然達不到四倍的性能,那也能達到1-2倍的效果。
Varnish和Squid的對比:
Squid 也是一種開源的代理緩存軟體,下面對比 Varnish 和 Squid 的不同點。
Varnish的穩定性很好。兩者在完成相同負載的工作時,Squid伺服器發生故障的幾率要高于Varnish,是以Squid需要經常重新開機。Varnish通路速度更快。Varnish采用了 Visual Page Cache技術,所有緩存的資料都直接從記憶體讀取,而Squid從硬碟讀取緩存的資料,是以Varnish在通路速度方面會更快一些。Varnish可以支援更多的并發連接配接。因為Varnish的TCP連接配接與釋放比Squid快,是以在高并發連接配接情況下可以支援更多的TCP連接配接。Varnish可以通過管理端口來管理緩存,使用正規表達式就可以批量清除部分緩存,而Squid做不到這一點。
Varnish缺點:
Varnish在高并發狀态下,CPU、I/O和記憶體等資源的開銷高于Squid。Varnish的程序一旦挂起、崩潰或者重新開機,緩存的資料都會從記憶體中釋放出來。此時的所有請求都會被發送到後端應用伺服器上,在高并發的情況下,就會給後端伺服器造成很大壓力。
一、安裝varnish
1.下載下傳:https://www.varnish-cache.org/releases/varnish-cache-3.0.3
1
2
3
4
5
<code>yum </code><code>install</code> <code>-y </code><code>make</code> <code>automake pkgconfig libtool pcre-devel </code><code>#安裝依賴包</code>
<code>tar</code> <code>zxvf varnish-3.0.3.</code><code>tar</code><code>.gz</code>
<code>.</code><code>/autogen</code><code>.sh</code>
<code>.</code><code>/configure</code> <code>--prefix=</code><code>/usr/local/varnish</code> <code>--</code><code>enable</code><code>-debugging-symbols --</code><code>enable</code><code>-developer-warnings --</code><code>enable</code><code>-dependency-tracking</code>
<code>make</code> <code>&& </code><code>make</code> <code>install</code>
2.建立使用者、組和日志檔案
<code>groupadd varnish</code>
<code>useradd</code> <code>-g varnish -s </code><code>/sbin/nologin</code> <code>varnish</code>
<code>touch</code> <code>/usr/local/varnish/access</code><code>.log </code><code>#建立通路日志檔案</code>
<code>chown</code> <code>-R varnish.varnish </code><code>/usr/local/varnish</code>
二、修改配置varnish
前端varnish緩存是以輪詢的方式分擔到後端web伺服器,以下vcl不對php進行緩存。
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<code>vi</code> <code>/usr/local/varnish/etc/varnish/default</code><code>.vcl</code>
<code> </code><code>backend web1 {</code>
<code> </code><code>.host = </code><code>"192.168.0.203"</code><code>; </code><code>#後端web1伺服器ip</code>
<code> </code><code>.port = </code><code>"80"</code><code>; </code><code>#通過80端口來通路後端web</code>
<code> </code><code>.connect_timeout = 1s; </code><code>#連接配接逾時時間</code>
<code> </code><code>.probe = {</code>
<code> </code><code>.url = </code><code>"/"</code><code>;</code>
<code> </code><code>.interval = 5s;</code>
<code> </code><code>.timeout = 1 s; </code><code>#檢測逾時時間</code>
<code> </code><code>.window = 5;</code>
<code> </code><code>.threshold = 3;</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>backend web2 {</code>
<code> </code><code>.host = </code><code>"192.168.0.204"</code><code>;</code>
<code> </code><code>.port = </code><code>"80"</code><code>;</code>
<code>director default round-robin { </code><code>#定義後端伺服器組,預設輪詢方式</code>
<code> </code><code>{</code>
<code> </code><code>.backend = web1;</code>
<code> </code><code>.backend = web2;</code>
<code>}</code>
<code> </code><code>sub vcl_recv {</code>
<code> </code><code>if</code> <code>(req.restarts == 0) {</code>
<code> </code><code>if</code> <code>(req.http.x-forwarded-</code><code>for</code><code>) {</code>
<code> </code><code>set</code> <code>req.http.X-Forwarded-For =</code>
<code> </code><code>req.http.X-Forwarded-For + </code><code>", "</code> <code>+ client.ip;</code>
<code> </code><code>else</code> <code>{</code>
<code> </code><code>set</code> <code>req.http.X-Forwarded-For = client.ip;</code>
<code> </code><code>if</code> <code>(req.request != </code><code>"GET"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"HEAD"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"PUT"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"POST"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"TRACE"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"OPTIONS"</code> <code>&&</code>
<code> </code><code>req.request != </code><code>"DELETE"</code><code>) {</code>
<code> </code><code>return</code> <code>(pipe);</code>
<code> </code><code>if</code> <code>(req.request != </code><code>"GET"</code> <code>&& req.request != </code><code>"HEAD"</code><code>) {</code>
<code> </code><code>return</code> <code>(pass);</code>
<code> </code><code>if</code> <code>(req.http.Authorization || req.http.Cookie) {</code>
<code> </code><code>return</code> <code>(lookup);</code>
<code> </code><code>sub vcl_pipe {</code>
<code> </code><code>sub vcl_pass {</code>
<code> </code><code>sub vcl_hash {</code>
<code> </code><code>hash_data(req.url);</code>
<code> </code><code>if</code> <code>(req.http.host) {</code>
<code> </code><code>hash_data(req.http.host);</code>
<code> </code><code>hash_data(server.ip);</code>
<code> </code><code>return</code> <code>(</code><code>hash</code><code>);</code>
<code> </code><code>sub vcl_hit {</code>
<code> </code><code>return</code> <code>(deliver);</code>
<code> </code><code>sub vcl_miss {</code>
<code> </code><code>return</code> <code>(fetch);</code>
<code> </code><code>sub vcl_fetch {</code>
<code> </code><code>if</code> <code>(beresp.ttl <= 0s ||</code>
<code> </code><code>beresp.http.Set-Cookie ||</code>
<code> </code><code>beresp.http.Vary == </code><code>"*"</code><code>) {</code>
<code> </code><code>set</code> <code>beresp.ttl = 120 s;</code>
<code> </code><code>return</code> <code>(hit_for_pass);</code>
<code> </code><code>sub vcl_deliver {</code>
<code> </code><code>sub vcl_error {</code>
<code> </code><code>set</code> <code>obj.http.Content-Type = </code><code>"text/html; charset=utf-8"</code><code>;</code>
<code> </code><code>set</code> <code>obj.http.Retry-After = </code><code>"5"</code><code>;</code>
<code> </code><code>synthetic {"</code>
<code> </code><code><?xml version=</code><code>"1.0"</code> <code>encoding=</code><code>"utf-8"</code><code>?></code>
<code> </code><code><!DOCTYPE html PUBLIC </code><code>"-//W3C//DTD XHTML 1.0 Strict//EN"</code>
<code> </code><code>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"</code><code>></code>
<code> </code><code><html></code>
<code> </code><code><</code><code>head</code><code>></code>
<code> </code><code><title></code><code>"} + obj.status + "</code> <code>" + obj.response + {"</code><code><</code><code>/title</code><code>></code>
<code> </code><code><</code><code>/head</code><code>></code>
<code> </code><code><body></code>
<code> </code><code><h1>Error </code><code>"} + obj.status + "</code> <code>" + obj.response + {"</code><code><</code><code>/h1</code><code>></code>
<code> </code><code><p></code><code>"} + obj.response + {"</code><code><</code><code>/p</code><code>></code>
<code> </code><code><h3>Guru Meditation:<</code><code>/h3</code><code>></code>
<code> </code><code><p>XID: </code><code>"} + req.xid + {"</code><code><</code><code>/p</code><code>></code>
<code> </code><code><hr></code>
<code> </code><code><p>Varnish cache server<</code><code>/p</code><code>></code>
<code> </code><code><</code><code>/body</code><code>></code>
<code> </code><code><</code><code>/html</code><code>></code>
<code> </code><code>"};</code>
<code> </code><code>sub vcl_init {</code>
<code> </code><code>return</code> <code>(ok);</code>
<code> </code><code>sub vcl_fini {</code>
語句解析:
Varnish處理請求的主要處理方法
1. vcl_recv
首先接收請求,判斷是否要進一步處理,還是直接轉發給後端(pass)等。 此過程中可以使用和請求相關的變量,例如用戶端請求的url,ip,user-agent,cookie等,此過程中可以把不需緩存的位址,通過判斷(相等、不相等、正則比對等方法)轉給後端,例如gif/png/jpg/css/js等靜态檔案;
2. vcl_fetch
當從後端伺服器擷取内容後會進入此階段,除了可以使用用戶端的請求變量,還可以使用從後端擷取的資訊(bersp),如後端傳回的頭資訊,設定此資訊的緩存時間TTL等;
3. vcl_miss
緩存未命中時中要做的處理
4. vcl_hit
緩存命中後做的處理
5. vcl_deliver
發送給用戶端前的處理
6. vcl_pass
交給後端伺服器
7. vcl_hash
設定緩存的鍵值key
Varnish處理流程
首次請求時過程如下:
recv->hash->miss->fetch->deliver
緩存後再次請求:
recv->hash->hit->deliver(fetch的過程沒了,這就是我們要做的,把要緩存的頁面儲存下來)
直接交給後端pass的情況:
recv->hash->pass->fetch->deliver(直接從後端擷取資料後發送給用戶端,此時Varnish相當于一個中轉站,隻負責轉發)
三、測試
1、啟動
<code>/usr/local/varnish/sbin/varnishd</code> <code>-f </code><code>/usr/local/varnish/etc/varnish/default</code><code>.vcl -s malloc,512M -g varnish -u varnish -T 127.0.0.1:2000 -a 0.0.0.0:80</code>
-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請求。
2、設定varnish通路日志
<code>/usr/local/</code><code>var</code><code>nish/bin/</code><code>var</code><code>nishncsa -n /usr/local/</code><code>var</code><code>nish/</code><code>var</code><code>/</code><code>var</code><code>nish/test.com -a -w /usr/local/</code><code>var</code><code>nish/access.log & #将</code><code>var</code><code>nish通路日志寫入到access.log裡</code>
<code>/usr/local/</code><code>var</code><code>nish/</code><code>var</code><code>/</code><code>var</code><code>nish/test.com :預設緩存目錄</code>
<code>netstat -tuplan |grep </code><code>var</code><code>nish #檢視是否啟動</code><code>2000</code><code>和</code><code>80</code><code>端口</code>
<code>tcp </code><code>0</code> <code>0</code> <code>0.0</code><code>.</code><code>0.0</code><code>:</code><code>80</code> <code>0.0</code><code>.</code><code>0.0</code><code>:* LISTEN </code><code>28551</code><code>/</code><code>var</code><code>nishd</code>
<code>tcp </code><code>0</code> <code>0</code> <code>127.0</code><code>.</code><code>0.1</code><code>:</code><code>2000</code> <code>0.0</code><code>.</code><code>0.0</code><code>:* LISTEN </code><code>28550</code><code>/</code><code>var</code><code>nishd</code>
<code>tcp </code><code>0</code> <code>0</code> <code>:::</code><code>80</code> <code>:::* LISTEN </code><code>28551</code><code>/</code><code>var</code><code>nishd</code>
<code>curl -I http:</code><code>//ip #使用curl指令檢視是否被緩存</code>
<code>killall -</code><code>9</code> <code>var</code><code>nishd #關閉</code><code>var</code><code>nish</code>
現在輸入varnish伺服器ip就可以通路到後端web伺服器!
3、設定開機啟動:
<code>echo</code> <code>'/usr/local/varnish/sbin/varnishd -f /usr/local/varnish/etc/varnish/default.vcl -s malloc,512M -g varnish -u varnish -T 127.0.0.1:2000 -a 0.0.0.0:80'</code> <code>>> </code><code>/etc/rc</code><code>.</code><code>local</code>
4、添加多個後端伺服器
如果添加多個後端網站伺服器,在default.vcl裡面添加不同網站的通路請求轉發到對應的backend去。
本文轉自 李振良OK 51CTO部落格,原文連結:http://blog.51cto.com/lizhenliang/1300036,如需轉載請自行聯系原作者