Linux varnish4.0緩存代理配置

2018-07-31 14:45 更新

防偽碼:你必須非常努力,才能看起來毫不費力。

一、varnish原理:

1)Varnish簡介:

varnish緩存是web應(yīng)用加速器,同時也作為http反向緩存代理。你可以安裝varnish在任何http的前端,同時配置它緩存內(nèi)容。與傳統(tǒng)的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等諸多優(yōu)點。有一部分企業(yè)已經(jīng)在生產(chǎn)環(huán)境中使用其作為舊版本的squid的替代方案,以在相同的服務(wù)器成本下提供更好的緩存效果,Varnish更是作為CDN緩存服務(wù)器的可選服務(wù)之一。

根據(jù)官網(wǎng)的介紹,Varnish的主要特性如下:https://www.varnish-cache.org/

1.緩存位置:可以使用內(nèi)存也可以使用磁盤。如果要使用磁盤的話推薦SSD做RAID1

2.日志存儲:日志也存儲在內(nèi)存中。存儲策略:固定大小,循環(huán)使用

3.支持虛擬內(nèi)存的使用。

4.有精確的時間管理機制,即緩存的時間屬性控制。

5.狀態(tài)引擎架構(gòu):在不同的引擎上完成對不同的緩存和代理數(shù)據(jù)進行處理。可以通過特定的配置語言設(shè)計不同的控制語句,以決定數(shù)據(jù)在不同位置以不同方式緩存,在特定的地方對經(jīng)過的報文進行特定規(guī)則的處理。

6.緩存管理:以二叉堆格式管理緩存數(shù)據(jù),做到數(shù)據(jù)的及時清理。

2)Varnish與Squid的對比

相同點:

都是一個反向代理服務(wù)器;

都是開源軟件;

Varnish的優(yōu)勢:

1、Varnish的穩(wěn)定性很高,兩者在完成相同負荷的工作時,Squid服務(wù)器發(fā)生故障的幾率要高于Varnish,因為使用Squid要經(jīng)常重啟;

2、Varnish訪問速度更快,因為采用了“Visual Page Cache”技術(shù),所有緩存數(shù)據(jù)都直接從內(nèi)存讀取,而squid是從硬盤讀取,因而Varnish在訪問速度方面會更快;

3、Varnish可以支持更多的并發(fā)連接,因為Varnish的TCP連接釋放要比Squid快,因而在高并發(fā)連接情況下可以支持更多TCP連接;

4、Varnish可以通過管理端口,使用正則表達式批量的清除部分緩存,而Squid是做不到的;

squid屬于是單進程使用單核CPU,但Varnish是通過fork形式打開多進程來做處理,所以可以合理的使用所有核來處理相應(yīng)的請求;

Varnish的劣勢:

1、varnish進程一旦Crash或者重啟,緩存數(shù)據(jù)都會從內(nèi)存中完全釋放,此時所有請求都會發(fā)送到后端服務(wù)器,在高并發(fā)情況下,會給后端服務(wù)器造成很大壓力;

2、在varnish使用中如果單個url的請求通過HA/F5等負載均衡,則每次請求落在不同的varnish服務(wù)器中,造成請求都會被穿透到后端;而且同樣的請求在多臺服務(wù)器上緩存,也會造成varnish的緩存的資源浪費,造成性能下降;

Varnish劣勢的解決方案:

針對劣勢一:在訪問量很大的情況下推薦使用varnish的內(nèi)存緩存方式啟動,而且后面需要跟多臺squid/nginx服務(wù)器。主要為了防止前面的varnish服 務(wù)、服務(wù)器被重啟的情況下,大量請求穿透varnish,這樣squid/nginx可以就擔(dān)當(dāng)?shù)诙覥ACHE,而且也彌補了varnish緩存在內(nèi)存中重啟都會釋放的問題;

針對劣勢二:可以在負載均衡上做url哈希,讓單個url請求固定請求到一臺varnish服務(wù)器上;

3)使用varnish作為web代理緩存的原理 :

varnish是一個http反向代理的緩存。它從客戶端接收請求然后嘗試從緩存中獲取數(shù)據(jù)來響應(yīng)客戶端的請求,如果varnish不能從緩存中獲得數(shù)據(jù)來響應(yīng)客戶端,它將轉(zhuǎn)發(fā)請求到后端(backend servers),獲取響應(yīng)同時存儲,最后交付給客戶端。 

如果varnish已經(jīng)緩存了某個響應(yīng),它比你傳統(tǒng)的后端服務(wù)器的響應(yīng)要快很多,所以你需要盡可能是更多的請求直接從varnish的緩存中獲取響應(yīng)。 

varnish決定是緩存內(nèi)容或者是從后端服務(wù)器獲取響應(yīng)。后端服務(wù)器能通過http響應(yīng)頭中的Cache-Control來同步varnish緩存內(nèi)容。在某些條件下varnish將不緩存內(nèi)容,最常見的是使用cookie。當(dāng)一個被標(biāo)記有cookie的客戶端web請求,varnish默認是不緩存。這些眾多的varnish功能特點都是可以通過寫vcl來改變的。

5)簡單架構(gòu):

Varnish 分為 management 進程和child 進程;

Management進程:對子進程進行管理,同時對VCL配置進行編譯,并應(yīng)用到不同的狀態(tài)引擎。

Child進程:生成線程池,負責(zé)對用戶請求進行處理,并通過hash查找返回用戶結(jié)果。

6)varnish主要配置部分:

varnish配置主要分為:后端配置,ACL配置,probes配置,directors配置,核心子程序配置幾大塊。其中后端配置是必要的,在多臺服務(wù)器中還會用到directors配置,核心子程序配置。

后端配置:即給varnish添加反代服務(wù)器節(jié)點,最少配置一個。

ACL配置:即給varnish添加訪問控制列表,可以指定這些列表訪問或禁止訪問。

probes配置:即給varnish添加探測后端服務(wù)器是否正常的規(guī)則,方便切換或禁止對應(yīng)后端服務(wù)器。

directors配置:即給varnish添加負載均衡模式管理多個后端服務(wù)器。

核心子程序配置:即給varnish添加后端服務(wù)器切換,請求緩存,訪問控制,錯誤處理等規(guī)則。

7)VCL中內(nèi)置預(yù)設(shè)變量:變量(也叫object):

1
2
3
4
5
6
7
8
eq:The request object,請求到達時可用的變量(客戶端發(fā)送的請求對象)
bereq:The backend request object,向后端主機請求時可用的變量
beresp:The backend response object,從后端主機獲取內(nèi)容時可用的變量(后端響應(yīng)請求對象)
resp:The HTTP response object,對客戶端響應(yīng)時可用的變量(返回給客戶端的響應(yīng)對象)
obj:存儲在內(nèi)存中時對象屬性相關(guān)的可用的變量(高速緩存對象,緩存后端響應(yīng)請求內(nèi)容)
預(yù)設(shè)變量是系統(tǒng)固定的,請求進入對應(yīng)的vcl子程序后便生成,這些變量可以方便子程序提取,當(dāng)然也可以自定義一些全局變量。
當(dāng)前時間:
now :作用:返回當(dāng)前時間戳。
1
2
3
4
客戶端:(客戶端基本信息)
client.ip:返回客戶端IP地址。
注:原client.port已經(jīng)棄用,如果要取客戶端請求端口號使用 std.port(client.ip),需要import std;才可以使用std
client.identity:用于裝載客戶端標(biāo)識碼。
1
2
3
4
5
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
服務(wù)器:(服務(wù)器基本信息)
注:原server.port已經(jīng)棄用,如果要取服務(wù)器端口號使用 std.port(server.ip),需要import std;才可以使用std
server.hostname:服務(wù)器主機名。
server.identity:服務(wù)器身份標(biāo)識。
server.ip:返回服務(wù)器端IP地址。
  
req :(客戶端發(fā)送的請求對象)
req:整個HTTP請求數(shù)據(jù)結(jié)構(gòu)
req.backend_hint:指定請求后端節(jié)點,設(shè)置后 bereq.backend 才能獲取后端節(jié)點配置數(shù)據(jù)
req.can_gzip:客戶端是否接受GZIP傳輸編碼。
req.hash_always_miss:是否強制不命中高速緩存,如果設(shè)置為true,則高速緩存不會命中,一直會從后端獲取新數(shù)據(jù)。
req.hash_ignore_busy:忽略緩存中忙碌的對象,多臺緩存時可以避免死鎖。
req.http:對應(yīng)請求HTTP的header。
req.method:請求類型(如 GET , POST)。
req.proto:客戶端使用的HTTP協(xié)議版本。
req.restarts:重新啟動次數(shù)。默認最大值是4
req.ttl:緩存有剩余時間。
req.url:請求的URL。
req.xid:唯一ID。
  
bereq:(發(fā)送到后端的請求對象,基于req對象)
bereq:整個后端請求后數(shù)據(jù)結(jié)構(gòu)。
bereq.backend:所請求后端節(jié)點配置。
bereq.between_bytes_timeout:從后端每接收一個字節(jié)之間的等待時間(秒)。
bereq.connect_timeout:連接后端等待時間(秒),最大等待時間。
bereq.first_byte_timeout:等待后端第一個字節(jié)時間(秒),最大等待時間。
bereq.http:對應(yīng)發(fā)送到后端HTTP的header信息。
bereq.method:發(fā)送到后端的請求類型(如:GET , POST)。
bereq.proto:發(fā)送到后端的請求的HTTP版本。
bereq.retries:相同請求重試計數(shù)。
bereq.uncacheable:無緩存這個請求。
bereq.url:發(fā)送到后端請求的URL。
bereq.xid:請求唯一ID。
  
beresp:(后端響應(yīng)請求對象)
beresp:整個后端響應(yīng)HTTP數(shù)據(jù)結(jié)構(gòu)。
beresp.backend.ip:后端響應(yīng)的IP。
beresp.backend.name:響應(yīng)后端配置節(jié)點的name。
beresp.do_gunzip:默認為 false 。緩存前解壓該對象
beresp.do_gzip:默認為 false 。緩存前壓縮該對象
beresp.grace:設(shè)置當(dāng)前對象緩存過期后可額外寬限時間,用于特殊請求加大緩存時間,當(dāng)并發(fā)量巨大時,不易設(shè)置過大否則會堵塞緩存,一般可設(shè)置 1m 左右,當(dāng)beresp.ttl=0s時該值無效。
beresp.http:對應(yīng)的HTTP請求header
beresp.keep:對象緩存后帶保持時間
beresp.proto:響應(yīng)的HTTP版本beresp.reason:由服務(wù)器返回的HTTP狀態(tài)信息
beresp.status:由服務(wù)器返回的狀態(tài)碼
beresp.storage_hint:指定保存的特定存儲器
beresp.ttl:該對象緩存的剩余時間,指定統(tǒng)一緩存剩余時間。
beresp.uncacheable:繼承bereq.uncacheable,是否不緩存
  
OBJ :(高速緩存對象,緩存后端響應(yīng)請求內(nèi)容)
obj.grace:該對象額外寬限時間
obj.hits:緩存命中次數(shù),計數(shù)器從1開始,當(dāng)對象緩存該值為1,一般可以用于判斷是否有緩存,當(dāng)前該值大于0時則為有緩存。
obj.http:對應(yīng)HTTP的header
obj.proto:HTTP版本
obj.reason:服務(wù)器返回的HTTP狀態(tài)信息
obj.status:服務(wù)器返回的狀態(tài)碼
obj.ttl:該對象緩存剩余時間(秒)
obj.uncacheable:不緩存對象
  
resp :(返回給客戶端的響應(yīng)對象)
resp:整個響應(yīng)HTTP數(shù)據(jù)結(jié)構(gòu)。
resp.http:對應(yīng)HTTP的header。
resp.proto:編輯響應(yīng)的HTTP協(xié)議版本。
resp.reason:將要返回的HTTP狀態(tài)信息。
resq.status:將要返回的HTTP狀態(tài)碼。
  
存儲 :
storage.<name>.free_space:存儲可用空間(字節(jié)數(shù))。
storage.<name>.used_space:存儲已經(jīng)使用空間(字節(jié)數(shù))。
storage.<name>.happy:存儲健康狀態(tài)。

8、特定功能性語句

1
2
3
4
5
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
ban(expression):清除指定對象緩存
call(subroutine):調(diào)用子程序,如:call(name);
hash_data(input):生成hash鍵,用于制定hash鍵值生成結(jié)構(gòu),只能在vcl_hash子程序中使用。調(diào)用 hash_data(input) 后,即這個hash為當(dāng)前頁面的緩存hash鍵值,無需其它獲取或操作,如:
sub vcl_hash{
       hash_data(client.ip);
       return(lookup);
}
注意:return(lookup); 是默認返回值,所以可以不寫。
new():創(chuàng)建一個vcl對象,只能在vcl_init子程序中使用。
return():結(jié)束當(dāng)前子程序,并指定繼續(xù)下一步動作,如:return (ok); 每個子程序可指定的動作均有不同。
rollback():恢復(fù)HTTP頭到原來狀態(tài),已經(jīng)棄用,使用 std.rollback() 代替。
synthetic(STRING):合成器,用于自定義一個響應(yīng)內(nèi)容,比如當(dāng)請求出錯時,可以返回自定義 404 內(nèi)容,而不只是默認頭信息,只能在 vcl_synth 與 vcl_backend_error 子程序中使用,如:
sub vcl_synth {
    //自定義內(nèi)容
    synthetic ({"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="zh-cn">
   <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
      <title>error</title>
   </head>
   <body>
      <h1>Error</h1>
      <h3>這只是一個測試自定義響應(yīng)異常內(nèi)容</h3>
   </body>
</html>
    "});
    //只交付自定義內(nèi)容
    return(deliver);
  
regsub(str, regex, sub):使用正則替換第一次出現(xiàn)的字符串,第一個參數(shù)為待處理字符串,第二個參數(shù)為正則表達式,第三個為替換為字符串。
regsuball(str, regex, sub):使用正則替換所有匹配字符串。參數(shù)與regsuball相同。
具體變量詳見:
https://www.varnish-cache.org/docs/4.0/reference/vcl.html#reference-vcl

(9)return 語句:

return 語句是終止子程序并返回動作,所有動作都根據(jù)不同的vcl子程序限定來選用。

https://www.varnish-cache.org/docs/4.0/users-guide/vcl-built-in-subs.html

語法:return(action);

常用的動作:

1
2
3
4
5
6
7
8
9
10
11
12
abandon  放棄處理,并生成一個錯誤。
deliver  交付處理
fetch  從后端取出響應(yīng)對象
hash  哈希緩存處理
lookup 查找緩存對象
ok 繼續(xù)執(zhí)行
pass  進入pass非緩存模式
pipe 進入pipe非緩存模式
purge 清除緩存對象,構(gòu)建響應(yīng)
restart 重新開始
retry 重試后端處理
synth(status code,reason) 合成返回客戶端狀態(tài)信息

10)varnish中內(nèi)置子程序有:

注:varnish內(nèi)置子程序均有自己限定的返回動作  return (動作);  不同的動作將調(diào)用對應(yīng)下一個子程序。

vcl_recv子程序:

開始處理請求,通過 return (動作); 選擇varnish處理模式,默認進入hash緩存模式(即return(hash);),緩存時間為配置項default_ttl(默認為 120秒)過期保持時間default_grace(默認為10秒)。該子程序一般用于模式選擇,請求對象緩存及信息修改,后端節(jié)點修改,終止請求等操作。

可操作對象:(部分或全部值)

1
2
3
4
5
6
7
8
讀:client,server,req,storage
寫:client,req
返回值:
synth(status code,reason);  定義響應(yīng)內(nèi)容。
pass  進入pass模式,并進入vcl_pass子程序。
pipe  進入pipe模式,并進入vcl_pipe子程序。
hash  進入hash緩存模式,并進入vcl_hash子程序,默認返回值。
purge  清除緩存等數(shù)據(jù),子程序先從vcl_hash再到vcl_purge。
1
2
3
4
5
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
vcl_pipe子程序:
pipe模式處理,該模式主要用于直接取后端響應(yīng)內(nèi)容返回客戶端,可定義響應(yīng)內(nèi)容返回客戶端。該子程序一般用于需要及時且不作處理的后端信息,取出后端響應(yīng)內(nèi)容后直接交付到客戶端不進入vcl_deliver子程序處理。
可操作對象:(部分或全部值)
讀:client,server,bereq,req,storage
寫:client,bereq,req
返回值:
synth(status code,reason);  定義響應(yīng)內(nèi)容。
pipe  繼續(xù)pipe模式,進入后端vcl_backend_fetch子程序,默認返回值。
  
vcl_pass子程序:
pass模式處理,該模式類似hash緩存模式,僅不做緩存處理。
可操作對象:(部分或全部值)
讀:client,server,req,storage
寫:client,req
返回值:
synth(status code,reason);  定義響應(yīng)內(nèi)容。
fetch  繼續(xù)pass模式,進入后端vcl_backend_fetch子程序,默認返回值。
  
vcl_hit子程序:
hash緩存模式時,存在hash緩存時調(diào)用,用于緩存處理,可放棄或修改緩存。
可操作對象:(部分或全部值)
讀:client,server,obj,req,storage
寫:client,req
返回值:
restart 重啟請求。
deliver 交付緩存內(nèi)容,進入vcl_deliver子程序處理,默認返回值。
synth(status code,reason);  定義響應(yīng)內(nèi)容。
  
vcl_miss子程序:
hash緩存模式時,不存在hash緩存時調(diào)用,用于判斷性的選擇進入后端取響應(yīng)內(nèi)容,可以修改為pass模式。
可操作對象:(部分或全部值)
讀:client,server,req,storage
寫:client,req
返回值:
restart 重啟請求。
synth(status code,reason);  定義響應(yīng)內(nèi)容。
pass 切換到pass模式,進入vcl_pass子程序。
fetch  正常取后端內(nèi)容再緩存,進入vcl_backend_fetch子程序,默認返回值。
  
vcl_hash子程序:
hash緩存模式,生成hash值作為緩存查找鍵名提取緩存內(nèi)容,主要用于緩存hash鍵值處理,可使用hash_data(string) 指定鍵值組成結(jié)構(gòu),可在同一個頁面通過IP或cookie生成不同的緩存鍵值。
可操作對象:(部分或全部值)
讀:client,server,req,storage
寫:client,req
返回值:
lookup 查找緩存對象,存在緩存進入vcl_hit子程序,不存在緩存進入vcl_miss子程序,當(dāng)使用了purge清理模式時會進入vcl_purge子程序,默認返回值。
  
vcl_purge子程序:
清理模式,當(dāng)查找到對應(yīng)的緩存時清除并調(diào)用,用于請求方法清除緩存,并報告。
可操作對象:(部分或全部值)
讀:client,server,req,storage
寫:client,req
返回值:
synth(status code,reason);  定義響應(yīng)內(nèi)容。
restart 重啟請求。
  
vcl_deliver子程序:
客戶端交付子程序,在vcl_backend_response子程序后調(diào)用(非pipe模式),或vcl_hit子程序后調(diào)用,可用于追加響應(yīng)頭信息,cookie等內(nèi)容。
可操作對象:(部分或全部值)
讀:client,server,req,resp,obj,storage
寫:client,req,resp
返回值:
deliver 正常交付后端或緩存響應(yīng)內(nèi)容,默認返回值。
restart 重啟請求。
  
vcl_backend_fetch子程序:
發(fā)送后端請求之前調(diào)用,可用于改變請求地址或其它信息,或放棄請求。
可操作對象:(部分或全部值)
讀:server,bereq,storage
寫:bereq
返回值:
fetch 正常發(fā)送請求到到后端取出響應(yīng)內(nèi)容,進入vcl_backend_response子程序,默認返回值。
abandon 放棄后端請求,并生成一個錯誤,進入vcl_backend_error子程序。
  
vcl_backend_response子程序:
后端響應(yīng)后調(diào)用,可用于修改緩存時間及緩存相關(guān)信息。
可操作對象:(部分或全部值)
讀:server,bereq,beresp,storage
寫:bereq,beresp
返回值:
deliver 正常交付后端響應(yīng)內(nèi)容,進入vcl_deliver子程序,默認返回值。
abandon 放棄后端請求,并生成一個錯誤,進入vcl_backend_error子程序。
retry 重試后端請求,重試計數(shù)器加1,當(dāng)超過配置中max_retries值時會報錯并進入vcl_backend_error子程序。
  
vcl_backend_error子程序:
后端處理失敗調(diào)用,異常頁面展示效果處理,可自定義錯誤響應(yīng)內(nèi)容,或修改beresp.status與beresp.http.Location重定向等。
可操作對象:(部分或全部值)
讀:server,bereq,beresp,storage
寫:bereq,beresp
返回值:
deliver 只交付 sysnthetic(string) 自定義內(nèi)容,默認返回后端異常標(biāo)準(zhǔn)錯誤內(nèi)容。
retry 重試后端請求,重試計數(shù)器加1,當(dāng)超過配置中max_retries值時會報錯并進入vcl_backend_error子程序。
  
vcl_synth子程序:
自定義響應(yīng)內(nèi)容。可以通過synthetic()和返回值 synth 調(diào)用,這里可以自定義異常顯示內(nèi)容,也可以修改resp.status與resp.http.Location重定向。
可操作對象:(部分或全部值)
讀:client,server,req,resp,storage
寫:req,resp
返回值:
deliver 只交付 sysnthetic(string) 自定義內(nèi)容,默認返回 sysnth 異常指定狀態(tài)碼與錯誤內(nèi)容。
restart 重啟請求。
  
vcl_init子程序:
加載vcl時最先調(diào)用,用于初始化VMODs,該子程序不參與請求處理,僅在vcl加載時調(diào)用一次。
可操作對象:(部分或全部值)
讀:server
寫:無
返回值:
ok 正常返回,進入vcl_recv子程序,默認返回值。
  
vcl_fini子程序:
卸載當(dāng)前vcl配置時調(diào)用,用于清理VMODs,該子程序不參與請求處理,僅在vcl正常丟棄后調(diào)用。
可操作對象:(部分或全部值)
讀:server
寫:無
返回值:
ok 正常返回,本次vcl將釋放,默認返回值。
varnish子程序調(diào)用流程圖,通過大部分子程序的return返回值進入下一步行動:

11)優(yōu)雅模式(Garce mode)

Varnish中的請求合并

當(dāng)幾個客戶端請求同一個頁面的時候,varnish只發(fā)送一個請求到后端服務(wù)器,然后讓其他幾個請求掛起并等待返回結(jié)果;獲得結(jié)果后,其它請求再復(fù)制后端的結(jié)果發(fā)送給客戶端;

但如果同時有數(shù)以千計的請求,那么這個等待隊列將變得龐大,這將導(dǎo)致2類潛在問題:

驚群問題(thundering herd problem),即突然釋放大量的線程去復(fù)制后端返回的結(jié)果,將導(dǎo)致負載急速上升;沒有用戶喜歡等待;

故為了解決這類問題,可以配置varnish在緩存對象因超時失效后再保留一段時間,以給那些等待的請求返回過去的文件內(nèi)容(stale content),配置案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
sub vcl_recv {
if (! req.backend.healthy) {
set req.grace = 5m;
else {
set req.grace = 15s;
}
}
sub vcl_fetch {
set beresp.grace = 30m;
}
以上配置表示varnish將會將失效的緩存對象再多保留30分鐘,此值等于最大的req.grace值即可;
而根據(jù)后端主機的健康狀況,varnish可向前端請求分別提供5分鐘內(nèi)或15秒內(nèi)的過期內(nèi)容

二、安裝varnish

1、安裝依賴關(guān)系的軟件包(注:使用centos在線yum源)

1
[root@varnish ~]# yum -y install autoconf automake libedit-devel libtool ncurses-devel pcre-devel pkgconfig python-docutils python-sphinx

2、安裝varnish

Varnish的官方網(wǎng)址為http://varnish-cache.org,可以在這里下載最新版本的軟件。

下載地址:https://www.varnish-cache.org/content/varnish-cache-403

注意:Varnish網(wǎng)站有時會被墻。

Git 下載:

1
git clone https://github.com/varnish/Varnish-Cache /var/tmp/

解壓,進入解壓目錄編譯安裝:

1
2
3
[root@varnish ~]# tar zxf varnish-4.0.3.tar.gz
[root@varnish ~]# cd varnish-4.0.3/
[root@varnish varnish-4.0.3]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

注:

./autogen.sh 

如果從Git庫下載的安裝包時才需要運行,用于生成configure編譯文件。

配置:

1
[root@varnish varnish-4.0.3]# ./configure

注:不指定安裝路徑,默認是安裝在/usr/local目錄下

編譯、安裝

1
[root@varnish varnish-4.0.3]# make && make install

復(fù)制 vcl 文件(在編譯安裝目錄下),如果安裝目錄里沒有 default.vcl 文件。

復(fù)制到安裝目錄的/usr/local/var/varnish/目錄下(當(dāng)然并無必需要求在哪個目錄,因為正式啟動時還得指定這個文件的目錄)

1
[root@varnish varnish-4.0.3]# cp etc/example.vcl  /usr/local/var/varnish/default.vcl

三、varnish實例解析:

varnish 配置基本上是編輯 VCL(Varnish Configuration Language) 文件,varnish 有一套自定義 VCL 語法,啟動時,會將配置文件編譯為C語言,再執(zhí)行。

varnish 4.0開始,每個VCL文件必須在開始行聲明它的版本“vcl 4.0;”

塊(子程序)由大括號分隔,語句用分號結(jié)束。所有的關(guān)鍵字及預(yù)設(shè)子程序名都是全小寫。

注釋:支持 // 或 #  多行時還可以使用 /* .. */

1、后端服務(wù)器地址池配置及后端服務(wù)器健康檢查

varnish有"后端"或者"源"服務(wù)器的概念。backend server提供給varnish加速的內(nèi)容。實際上就是給varnish添加可供訪問的web服務(wù)器,如果有多臺web服務(wù)器時,可添加多個backend塊。

1)后端服務(wù)器定義:

命令:backend。這個定義為最基本的反向入口定義,用于varnish連接對應(yīng)的服務(wù)器,如果沒有定義或定義錯誤則用戶無法訪問正常頁面。

語法格式:

1
2
3
backend name{
    .attribute = "value";
}

說明:backend 是定義后端關(guān)鍵字,name 是當(dāng)前后端節(jié)點的別名,多個后端節(jié)點時,name 名不能重復(fù),否則覆蓋?;ɡㄌ柪锩娑x當(dāng)前節(jié)點相關(guān)的屬性(鍵=值)。除默認節(jié)點外其它節(jié)點定義后必需有調(diào)用,否則varnish無法啟動。后端是否正??梢酝ㄟ^std.healthy(backend)判斷。

支持運算符:

=   (賦值運算)

==  (相等比較)

~    (匹配,可以使用正則表達式,或訪問控制列表)

!~    (不匹配,可以使用正則表達式,或訪問控制列表)

!  (非)

&&   (邏輯與)

||   (邏輯或)

屬性列表:

.host="xxx.xxx.xxx.xxx";      //要轉(zhuǎn)向主機(即后端主機)的IP或域名,必填鍵/值對。
.port="8080";        //主機連接端口號或協(xié)議名(HTTP等),默認80
.host_header='';    //請示主機頭追加內(nèi)容
.connect_timeout=1s;     //連接后端的超時時間
.first_byte_timeout=5s;    //等待從后端返回的第一個字節(jié)時間
.between_bytes_timeout=2s;     //每接收一個字節(jié)之間等待時間
.probe=probe_name;        //監(jiān)控后端主機的狀態(tài),指定外部監(jiān)控name或者內(nèi)部直接添加
.max_connections=200;    //設(shè)置最大并發(fā)連接數(shù),超過這個數(shù)后連接就會失敗

例:(下面兩個例子結(jié)果是一樣的,但第二個例子中更適用于集群,可以方便批量修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
backend web{
    .host="192.168.31.83";
    .port="80";
    .probe={          //直接追加監(jiān)控塊.probe是一個的參數(shù)
        .url="/";
        .timeout=2s;
    }
}
probe web_probe{   //監(jiān)控必需定義在前面,否則后端調(diào)用找不到監(jiān)控塊。
    .url="/";
    .timeout=2s;
}
  
backend web{
    .host="192.168.31.83";
    .port="80";
    .probe=web_probe;   //調(diào)用外部共用監(jiān)控塊
}

2)監(jiān)視器定義:

命令:probe 。監(jiān)控可以循環(huán)訪問指定的地址,通過響應(yīng)時間判定服務(wù)器是否空閑或正常。這類命令非常適用于集群中某些節(jié)點服務(wù)器崩潰或負載過重,而禁止訪問這臺節(jié)點服務(wù)器。

語法格式:

1
2
3
probe name{
    .attribute = "value";
}

說明:probe 是定義監(jiān)控關(guān)鍵字,name 是當(dāng)前監(jiān)控點的別名,多個監(jiān)控節(jié)點時,name 名不能重復(fù),否則覆蓋。花括號里面定義當(dāng)前節(jié)點相關(guān)的屬性(鍵=值)。

沒有必填屬性,因為默認值就可以正常執(zhí)行操作。

屬性列表:

.url="/";    //指定監(jiān)控入口URL地址,默認為"/"

.request="";   //指定監(jiān)控請求入口地址,比 .url 優(yōu)先級高。
.expected_response="200";   //請求響應(yīng)代碼,默認是 200
.timeout=2s;   //請求超時時間。
.interval=5s;     //每次輪詢請求間隔時間,默認為 5s 。
.initial=-1;     //初始啟動時以.window輪詢次數(shù)中幾次良好后續(xù)才能使用這個后端服務(wù)器節(jié)點,默認為 -1 ,則輪詢完 .window 所有次數(shù)良好判定為正常。
.window=8;   //指定多少輪詢次數(shù),用于判定服務(wù)器正常,默認是 8。
.threshold=3;   //必須多少次輪詢正常才算該后端節(jié)點服務(wù)器正常,默認是 3。

例:創(chuàng)建健康監(jiān)測,定義健康檢查名稱為backend_healthcheck

1
2
3
4
5
6
7
probe backend_healthcheck {
        .url = "/";
        .timeout = 1s;
        .interval = 5s;
        .window = 5;
        .threshold = 3;
    }

在上面的例子中varnish將每5s檢測后端,超時設(shè)為1s。每個檢測將會發(fā)送get /的請求。如果5個檢測中大于3個是成功,varnish就認為后端是健康的,反之,后端就有問題了。

 

3)集群負載均衡directors:

varnish可以定義多個后端,也可以將幾個后端放在一個后端集群里面已達到負載均衡的目的。

你也可以將幾個后端組成一組后端。這個組被叫做Directors??梢蕴岣咝阅芎蛷椥?。

directors是varnish負載均衡模塊,使用前必需引入directors模塊,directors模塊主要包含:round_robin,random,hash,fallback負載均衡模式。

round_robin : 循環(huán)依次逐個選擇后端服務(wù)器。

random : 隨機選擇后端服務(wù)器,可設(shè)置每個后端權(quán)重增加隨機率。

hash :  通過散列隨機選擇對應(yīng)的后端服務(wù)器且保持選擇對應(yīng)關(guān)系,下次則直接找對應(yīng)的后端服務(wù)器。

Fallback:后備

注意:random,hash 有權(quán)重值設(shè)置,用于提高隨機率。每個后端最好都配置監(jiān)控器(后端服務(wù)器正常監(jiān)測)以便directors自動屏蔽不正常后端而不進入均衡列隊中。

這些操作需要你載入VMOD(varnish module),然后在vcl_init中調(diào)用這個VMOD。

1
2
3
4
5
6
7
8
9
10
11
import directors;                # load the directors
backend web1 {
.host = "192.168.0.10";
.port = "80";
.probe = backend_healthcheck;
}
backend web2 {
.host = "192.168.0.11";
.port = "80";
.probe = backend_healthcheck;
}

//初始化處理

sub vcl_init {            //調(diào)用vcl_init初始化子程序創(chuàng)建后端主機組,即directors

    new  web_cluster = directors.round_robin(); //使用new關(guān)鍵字創(chuàng)建drector對象,使用round_robin算法

    web_cluster.add_backend(web1);   //添加后端服務(wù)器節(jié)點

web_cluster.add_backend(web2);

}

//開始處理請求

sub vcl_recv {                     //調(diào)用vcl_recv子程序,用于接收和處理請求

    set  req.backend_hint = web_cluster.backend();     //選取后端

}

說明:

set命令是設(shè)置變量

unset命令是刪除變量

web_cluster.add_backend( backend , real );  添加后端服務(wù)器節(jié)點,backend 為后端配置別名,real 為權(quán)重值,隨機率計算公式:100 * (當(dāng)前權(quán)重 / 總權(quán)重)。

req.backend_hint是varnish的預(yù)定義變量,作用是指定請求后端節(jié)點

vcl對象需要使用new關(guān)鍵字創(chuàng)建,所有可創(chuàng)建對象都是內(nèi)定的,使用前必需import,所有new操作只能在vcl_init子程序中。

擴展:varnish將不同的url發(fā)送到不同的后端server

i

1
2
3
4
5
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
mport directors;                # load the directors
backend web1 {
.host = "192.168.0.10";
.port = "80";
.probe = backend_healthcheck;
}
backend web2 {
.host = "192.168.0.11";
.port = "80";
.probe = backend_healthcheck;
}
backend img1 {
        .host = "img1.lnmmp.com";
        .port = "80";
        .probe = backend_healthcheck;
}
backend img2 {
        .host = "img2.lnmmp.com";
        .port = "80";
        .probe = backend_healthcheck;
}
//初始化處理
sub vcl_init {            //調(diào)用vcl_init初始化子程序創(chuàng)建后端主機組,即directors
    new  web_cluster = directors.round_robin(); //使用new關(guān)鍵字創(chuàng)建drector對象,使用round_robin算法
    web_cluster.add_backend(web1);   //添加后端服務(wù)器節(jié)點
web_cluster.add_backend(web2);
new img_cluster = directors.random();
img_cluster.add_backend(img1,2);   //添加后端服務(wù)器節(jié)點,并且設(shè)置權(quán)重值
img_cluster.add_backend(img2,5);
}
//根據(jù)不同的訪問域名,分發(fā)至不同的后端主機組
sub vcl_recv {
if (req.http.host  ~  "(?i)^(www.)?benet.com$") {
                set  req.http.host = "www.benet.com";
                set  req.backend_hint = web_cluster.backend();  //選取后端
        } elsif (req.http.host  ~  "(?i)^images.benet.com$") {
            set  req.backend_hint = img_cluster.backend();
        }
}

說明:中的i就是忽略大小寫的意思。(?i)表示開啟忽略大小寫,而(?-i)表示關(guān)閉忽略大小寫

 

4)訪問控制列表(ACL):

創(chuàng)建一個地址列表,用于后面的判斷,可以是域名或IP集合。這個可以用于指定某些地址請求入口,防止惡意請求等。

語法格式:

1
2
3
4
5
6
acl  purgers  {
    "127.0.0.1";
"localhost";
“192.168.134.0/24
    !"192.168.134.1";
}

說明:acl 是訪問列表關(guān)鍵字(必需小寫),name 是該列表的別名用于調(diào)用,花括號內(nèi)部是地址集。

注意:如果列表中包含了無法解析的主機地址,它會匹配任何地址。

如果不想讓它匹配可以在前添加一個 ! 符號,如上面 !"192.168.134.1"; 

使用ACL只需要用 匹配運算符 ~ 或 !~  如:

1
2
3
4
5
6
7
8
9
sub  vcl_recv {
    if  (req.method == "PURGE") {    //PURGE請求的處理
         if  (client.ip  ~  purgers) {
              return(purge);
         else {
            return(synth(403, "Access denied."));
        }
    }
}

5)緩存規(guī)則配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
sub vcl_recv {
  // PURGE請求的處理
  if (req.method == "PURGE") {
    if (!client.ip ~ purgers) {
      return (synth(405, "Not Allowed."));
    }
    return (purge);
  }
  
  set req.backend_hint = web.backend();
  
  //將php、asp等動態(tài)內(nèi)容訪問請求直接發(fā)給后端服務(wù)器,不緩存。
  if (req.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {
    return (pass);
  }
  //將非GET和HEAD訪問請求直接發(fā)給后端服務(wù)器,不緩存。例如POST請求。
  if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
  }
  //如果varnish看到header中有'Authorization'頭,它將pass請求。
  if (req.http.Authorization) {
        return (pass);
}
  
  //帶cookie首部的GET請求也緩存
  if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
    unset req.http.cookie;
    return (hash);
  }

說明:默認情況,varnish不緩存從后端響應(yīng)的http頭中帶有Set-Cookie的對象。如果客戶端發(fā)送的請求帶有Cookie header,varnish將忽略緩存,直接將請求傳遞到后端。

 

//為發(fā)往后端主機的請求添加X-Forward-For首部,首次訪問增加 X-Forwarded-For 頭信息,方便后端程序獲取客戶端ip,而不是varnish地址

1
2
3
4
5
6
7
if (req.restarts == 0) {
        if (req.http.x-forwarded-for) {//如果設(shè)置過此header則要再次附加上用逗號隔開
            set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        else {//如果只有一層代理的話,就無需設(shè)置了
            set req.http.X-Forwarded-For = client.ip;
        }
}

說明:X-Forwarded-For 是用來識別通過HTTP代理或負載均衡方式連接到Web服務(wù)器的客戶端最原始的IP地址的HTTP請求頭字段

子程序:

 

子程序是一種類似C的函數(shù),但是程序沒有調(diào)用參數(shù),子程序以 sub 關(guān)鍵字定義。在VCL里子程序是用于管理程序。

注意:所有VCL內(nèi)置的程序都是以 vcl_ 開頭,并已經(jīng)預(yù)置好,在VCL文件中只要聲明對應(yīng)的內(nèi)置子程序,都會在對應(yīng)的流程中調(diào)用。

三、varnish完整配置實例

1、拓撲環(huán)境

1
2
3
Varnish:192.168.31.250
Web01:192.168.31.83
Web02:192.168.31.141

配置web01、web02做為后端服務(wù)器(過程略)

確保varnish服務(wù)器能正常訪問web01、web02

Varnish緩存代理服務(wù)器配置:

2、vcl文件配置內(nèi)容:

1
[root@varnish ~]# cat  /usr/local/var/varnish/default.vcl

#使用varnish版本4的格式.

1
vcl 4.0;

#加載后端負載均衡模塊

1
import directors;

#加載std模塊

1
import std;

#創(chuàng)建名為backend_healthcheck的健康檢查策略

1
2
3
4
5
6
7
probe backend_healthcheck {
    .url="/";
    .interval = 5s;
    .timeout = 1s;
    .window = 5;
    .threshold = 3;
}

#定義后端服務(wù)器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
backend web_app_01 {
    .host = "192.168.31.83";
    .port = "80";
    .first_byte_timeout = 9s;
    .connect_timeout = 3s;
    .between_bytes_timeout = 1s;
    .probe = backend_healthcheck;
}
backend web_app_02 {
    .host = "192.168.31.141";
    .port = "80";
    .first_byte_timeout = 9s;
    .connect_timeout = 3s;
    .between_bytes_timeout = 1s;
    .probe = backend_healthcheck;
}

#定義允許清理緩存的IP

1
2
3
4
5
acl purgers {
    "127.0.0.1";
    "localhost";
    "192.168.31.0/24";
}

#vcl_init初始化子程序創(chuàng)建后端主機組

1
2
3
4
5
sub vcl_init {
    new web = directors.round_robin();
    web.add_backend(web_app_01);
    web.add_backend(web_app_02);
}

#請求入口,用于接收和處理請求。這里一般用作路由處理,判斷是否讀取緩存和指定該請求使用哪個后端

1
2
3
4
5
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
sub vcl_recv {
    #將請求指定使用web后端集群 .在集群名后加上 .backend()
set req.backend_hint = web.backend();
# 匹配清理緩存的請求
    if (req.method == "PURGE") {
        if (!client.ip ~ purgers) {
            return (synth(405, "Not Allowed."));
        }
        # 是的話就執(zhí)行清理
        return (purge);
    }
    # 如果不是正常請求 就直接穿透沒商量
    if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "PATCH" &&
      req.method != "DELETE") {
      return (pipe);
    }
    # 如果不是GET和HEAD就跳到pass 
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }
    #如果匹配動態(tài)內(nèi)容訪問請求就跳到pass
    if (req.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {
        return (pass);
    }
    #具有身份驗證的請求跳到pass
    if (req.http.Authorization) {
        return (pass);
    }
  
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$") {
            unset req.http.Accept-Encoding;
        } elseif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elseif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        else {
            unset req.http.Accept-Encoding;
        }
    }
  
    if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
        unset req.http.cookie;
        return (hash);
}

# 把真實客戶端IP傳遞給后端服務(wù)器 后端服務(wù)器日志使用X-Forwarded-For來接收

   

1
2
3
4
5
6
7
8
9
 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;
        }
    }
    return (hash);
}

# hash事件(緩存事件)

1
2
3
4
5
6
7
8
9
sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    else {
        hash_data(server.ip);
    }
    return (lookup);
}

# 緩存命中事件

1
2
3
4
5
6
sub vcl_hit {
    if (req.method == "PURGE") {
        return (synth(200, "Purged."));
    }
    return (deliver);
}

# 緩存不命中事件

1
2
3
4
5
6
sub vcl_miss {
    if (req.method == "PURGE") {
        return (synth(404, "Purged."));
    }
    return (fetch);
}

# 返回給用戶的前一個事件 通常用于添加或刪除header頭

1
2
3
4
5
6
7
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
    else {
        set resp.http.X-Cache = "MISS";
}

#取消顯示php框架版本的header頭

1
unset resp.http.X-Powered-By;

#取消顯示web軟件版本、Via(來自varnish)等header頭 為了安全

   

1
2
3
4
5
 unset resp.http.Server;
    unset resp.http.X-Drupal-Cache;
    unset resp.http.Via;
    unset resp.http.Link;
unset resp.http.X-Varnish;
1
2
3
4
5
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
#顯示請求經(jīng)歷restarts事件的次數(shù)
set resp.http.xx_restarts_count = req.restarts;
#顯示該資源緩存的時間單位秒
set resp.http.xx_Age = resp.http.Age;
#顯示該資源命中的次數(shù)
set resp.http.hit_count = obj.hits;
#取消顯示Age 為了不和CDN沖突
unset resp.http.Age;
#返回給用戶
    return (deliver);
}
# pass事件
sub vcl_pass {
    return (fetch);
}
#處理對后端返回結(jié)果的事件(設(shè)置緩存、移除cookie信息、設(shè)置header頭等) 在fetch事件后自動調(diào)用
sub vcl_backend_response {
    #開啟grace模式 表示當(dāng)后端全掛掉后 即使緩存資源已過期(超過緩存時間) 也會把該資源返回給用戶 資源最大有效時間為5分鐘
set beresp.grace = 5m;
#后端返回如下錯誤狀態(tài)碼 則不緩存
    if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) {
    set beresp.uncacheable = true;
}
#如請求php或jsp 則不緩存
    if (bereq.url ~ "\.(php|jsp)(\?|$)") {
      set beresp.uncacheable = true;
    else //自定義緩存文件的緩存時長,即TTL值
       if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") {
         set beresp.ttl = 15m;
         unset beresp.http.Set-Cookie;
       } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
           set beresp.ttl = 30m;
           unset beresp.http.Set-Cookie;
         else {
            set beresp.ttl = 10m;
            unset beresp.http.Set-Cookie;
         }
      }
    #返回給用戶
    return (deliver);
}
sub vcl_purge {
        return (synth(200,"success"));
}
  
sub vcl_backend_error {
    if (beresp.status == 500 ||
        beresp.status == 501 ||
        beresp.status == 502 ||
        beresp.status == 503 ||
        beresp.status == 504) {
        return (retry);
    }
}
  
sub vcl_fini {
    return (ok);
}

3、啟動varnish

當(dāng)啟動varnish時有兩個重要的參數(shù)你必須設(shè)置: 一個是處理http請求的tcp監(jiān)聽端口,另一個是處理真實請求的后端server

注:如果你使用操作系統(tǒng)自帶的包管理工具安裝的varnish,你將在下面的文件找到啟動參數(shù):

Red Hat, Centos: /etc/sysconfig/varnish


1):'-a' 參數(shù)定義了varnish監(jiān)聽在哪個地址,并用該地址處理http請求,你可能想設(shè)置這個參數(shù)在眾所周知的http 80端口.

例子:

-a  :80

-a  localhost:80

-a  192.168.1.100:8080

-a  '[fe80::1]:80'

-a  '0.0.0.0:8080,[::]:8081'

如果你的webserver和varnish運行在同一臺機器,你必須換一個監(jiān)聽地址.

2):'-f'  VCL-file  or  '-b'  backend

-f添加vcl文件,-b定義后端server

varnish需要知道從哪里找到這個需要緩存的http server.你可以用-b參數(shù)指定,或者幫把它放在vcl文件中,然后使用-f參數(shù)指定.

在啟動的時候使用-b是一個快捷的方式.

-b 192.168.1.2:80

注意:如果你指定的是name,這個name必須能解析成一個IPv4或者IPv6的地址

如果你使用-f參數(shù),你啟動的時候可以在-f指定vcl文件。

默認的varnish使用100M的內(nèi)存來緩存對象,如果你想緩存更多,可以使用-s參數(shù). 

注:Varnish擁有大量的有用的命令行參數(shù),建議查看其幫助

1
[root@varnish ~]# /usr/local/sbin/varnishd -h

啟動varnish

1
2
3
4
[root@varnish ~]# /usr/local/sbin/varnishd -f /usr/local/var/varnish/default.vcl -s malloc,200M -a
0.0.0.0:80
[root@varnish ~]# netstat -anpt | grep 80
tcp     0   0 0.0.0.0:80      0.0.0.0:*      LISTEN      6173/varnishd

2)現(xiàn)在,varnish已經(jīng)啟動和運行,你可以通過varnish訪問您的Web應(yīng)用程序。

打開火狐瀏覽器

第一次訪問

第二次訪問

3)varnish4配置手動清除緩存

varnish4通過vcl配置清楚緩存

通過vcl配置可以讓客戶端手動請求清楚緩存,以保證局部數(shù)據(jù)及時更新,而不用重啟varnish服務(wù)器。

配置方法:

#允許清除緩存IP集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
acl purgers {
    "127.0.0.1";
    "localhost";
    "192.168.31.0/24";
}
sub vcl_recv {
    ……
    if (req.method == "PURGE") {
        if (!client.ip ~ purgers) {
            return (synth(405, "Not Allowed."));
        }
        return (purge);   //清除緩存
}
……
}
sub vcl_purge {
        return (synth(200,"success"));
}


打開火狐瀏覽器,隨便進入一個緩存頁面,如下圖所示。

點擊編輯和重發(fā), 修改請求類型為 PURGE 再點擊 發(fā)送

查看返回狀態(tài),如果成功則成功清除緩存,可以按 F5 刷新頁面,查看新內(nèi)容。

 


本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號