varnish簡介
Varnish是一個輕量級的Cache和反向代理軟件,先進的設計理念和成熟的設計框架是Varnish的主要特點,現在的Varnish總共代碼量不大,功能上雖然在不斷改進,但是還需要繼續豐富和加強。下面總結了Varnish的一些特點:
(1)是基於內存緩存,重啓後數據將消失。
(2)利用虛擬內存方式,io性能好。
(3)支持設置0~60秒內的精確緩存時間。
(4)VCL配置管理比較靈活。
(5)32位機器上緩存文件大小爲最大2G。
(6)具有強大的管理功能,例如top,stat,admin,list等。
(7)狀態機設計巧妙,結構清晰。
(8)利用二叉堆管理緩存文件,達到積極刪除目的。
varnish的工作原理
varnish的存儲方式
varnish有三種有存儲方式:
1、file:存儲在磁盤空間,但是在varnish重啓後會被清除;其通過mmap()系統調用將緩存文件映射到內存空間
2、malloc:存儲在內存空間,其通過malloc()庫調用在varnish啓動時申請置頂大小的內存空間用於存儲緩存對象
3、persistent:與file一樣,但是可以永久存儲緩存文件,但其現處於測試階段
選定存儲方式:
1、在varnished啓動時使用-s選項指定:
malloc [,size]
file [,path[,size[,granularity]]]
persistent,path,size {experimental}
2、在配置文件中修改:
#vim /etc/sysconfig/varnish
varnish的狀態引擎
VCL用於讓管理員定義緩存策略,而定義好的策略將由varnish的management進程分析、轉換成代碼、編譯成二進制程序並連接至child進程。varnish內部有幾個所謂的狀態(state),在這些狀態上可以附加通過VCL定義的策略以完成相應的緩存處理機制,因此VCL也經常被稱作“域專用”語言或狀態引擎,“域專用”指的是有些數據僅出現於特定的狀態中。
vcl_recv:用於接受和處理請求,成功接受到後根據數據來決定如何處理請求:
vcl_pipe:將請求直接爨地至後端主機,在請求和返回內容沒有改變的前提下將不變的內容返回給客戶端
vcl-pass:將請求發送給後端主機,且後端主機返回的數據不緩存,直接傳送給用戶
vcl_hash:在hash表中查找緩存的對象產生hit或miss兩種狀態
vcl_hit:請求的數據命中後會執行兩種情況:1)丟棄,重新向後端主機發起請求;2)將結果執行deliver
vcl_miss:在該狀態有兩種方式進行fetch,一種是以pass執行,獲取結果不緩存;一種是直接執行fetch,獲取的結果緩存
vcl_fetch:從主機更新緩存並且獲取內容,通過獲取的內容來判斷是否緩存
vcl_deliver:將獲取的數據傳送給客戶端
vcl_tiomeout:此函數在緩存內容到期後使用
vcl_discard:在緩存內容到期或空間不足時調用
在完整的請求處理流程中會有如下集中模式:pipe、looku、pass、deliver
或者是直接向用戶返回error code [reason] :返回code給客戶端,並放棄處理該請求
處理http請求的有一下幾個關鍵性步驟:
receive狀態:處理請求的路口狀態,通過vcl規則判斷是將請求pass還是pipe、或者進入lookup狀態查詢本地緩存
lookup狀態:在hash表中查找數據,命中進入hit狀態,未命中進入miss狀態
fetch狀態:對後端發起請求,獲得數據;的到出局後可以選擇在本地緩存後執行deliver或者直接執行deliver
deliver狀態:將獲取到的數據發送給客戶端,完成本次請求
varnish的Director支持的算法
round-roubin:這種類型沒有參數,只需要爲其指定後端主機即可,就能活後端的主機進行輪詢,當主機故障時則不在挑選
random:隨機從後端主機中進行挑選,每個主機狗需要指定一個.weight參數,同時還可以使用.reties爲direcotr級別設定查找健康後端的嘗試次數
//在2.1.0後
vcl的部分變量
當請求到達後可以使用的vcl內置的功用變量
變量名稱 | 含義 |
req.backend | 制定對應的後端主機 |
server.ip | 表示服務器端的IP |
client.ip | 表示客戶端的IP |
req.request | 制定請求的類型,如GET,GEAD,PUT |
req.url | 指定請求的地址 |
req.proto | 表示客戶端請求的HTTP版本 |
req.http.header | 表示對應請求中的HTTP頭部信息 |
req.restarts | 表示請求重啓的次數,默認最大值爲4 |
變量名稱 | 含義 |
beresp.request | 指定請求的類型,如GET、HEAD等 |
beresp.url | 指定請求的地址 |
beresp.proto | 表示向客戶端發起請求的HTTP版本 |
beresp.http.header | 表示對應請求中的首部信息 |
beresp.ttl | 表示緩存的生存週期,單位是秒 |
從cache或後端主機獲取到內容後使用的變量
obj.status | 表示返回內容的請求狀態碼,如200、504等 |
obj.cachetable | 表示返回的內容是否可以緩存,由HTTP返回的狀態碼且生存週期不爲零,則可以緩存 |
obj.valid | 表示是否是有效的HTTP應答 |
obj.response | 返回內容的請求狀態信息 |
obj.proto | 返回內容的HTTP協議版本 |
obj.ttl | 返回內容的緩存時間,單位秒 |
obj.lasture | 表示上一次請求到現在的間隔時間,單位秒 |
對客戶端應答是使用的變量
resp.status | 返回給客戶端的HTTP狀態代碼 |
resp.proto | ...協議版本 |
resp.http.header | ...頭部信息 |
resp.response | ...狀態信息 |
與緩存的HTTP首部
cache-control
對緩存進行控制,如一個請求希望響應返回的內容在客戶端要被緩存一年,或不希望被緩存就可以通過這個報文頭達到目的。
max-age:(只接受 Age 值小於 max-age 值,並且沒有過期的對象)
max-stale:(可以接受過去的對象,但是過期時間必須小於 max-stale 值)
min-fresh:(接受其新鮮生命期大於其當前 Age 跟 min-fresh 值之和的緩存對象)
響應:public(可以用 Cached 內容迴應任何用戶)
private(只能用緩存內容迴應先前請求該內容的那個用戶)
no-cache(可以緩存,但是只有在跟WEB服務器驗證了其有效後,才能返回給客戶端)
max-age:(本響應包含的對象的過期時間)
ALL: no-store(不允許緩存)
Vary: WEB服務器用該頭部的內容告訴 Cache 服務器,在什麼條件下才能用本響應所返回的對象響應後續的請求。假如源WEB服務器在接到第一個請求消息時,其響應消息的頭部爲:Content- Encoding: gzip; Vary: Content-Encoding那麼 Cache 服務器會分析後續請求消息的頭部,檢查其 Accept-Encoding,是否跟先前響應的 Vary 頭部值一致,即是否使用相同的內容編碼方法,這樣就可以防止 Cache 服務器用自己 Cache 裏面壓縮後的實體響應給不具備解壓能力的瀏覽器。
例如:Vary:Accept-Encoding
Via: 列出從客戶端到 OCS 或者相反方向的響應經過了哪些代理服務器,他們用什麼協議(和版本)發送的請求。當客戶端請求到達第一個代理服務器時,該服務器會在自己發出的請求裏面添 加 Via 頭部,並填上自己的相關信息,當下一個代理服務器收到第一個代理服務器的請求時,會在自己發出的請求裏面複製前一個代理服務器的請求的Via 頭部,並把自己的相關信息加到後面,以此類推,當 OCS 收到最後一個代理服務器的請求時,檢查 Via 頭部,就知道該請求所經過的路由。
例如:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)
ETag:就是一個對象(比如URL)的標誌值,就一個對象而言,比如一個 html 文件,如果被修改了,其 Etag 也會別修改,所以ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服務器判斷一個對象是否改變了。比如前一次請求某個 html 文件時,獲得了其 ETag,當這次又請求這個文件時,瀏覽器就會把先前獲得的 ETag 值發送給WEB 服務器,然後 WEB 服務器會把這個 ETag 跟該文件的當前 ETag 進行對比,然後就知道這個文件有沒有改變了。
Expired:WEB服務器表明該實體將在什麼時候過期,對於過期了的對象,只有在跟WEB服務器驗證了其有效性後,才能用來響應客戶請求。是 HTTP/1.0 的頭部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT
Host:客戶端指定自己想訪問的WEB服務器的域名/IP 地址和端口號。例如:Host:rss.sina.com.cn
If-Match:如果對象的 ETag 沒有改變,其實也就意味著對象沒有改變,才執行請求的動作。
If-None-Match:如果對象的 ETag 改變了,其實也就意味著對象也改變了,才執行請求的動作。
If-Modified-Since:如果請求的對象在該頭部指定的時間之後修改了,才執行請求的動作(比如返回對象),否則返回代碼304,告訴瀏覽器 該對象沒有修改。
例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
If-Unmodified-Since:如果請求的對象在該頭部指定的時間之後沒修改過,才執行請求的動作(比如返回對象)。
If-Range:瀏覽器告訴 WEB 服務器,如果我請求的對象沒有改變,就把我缺少的部分給我,如果對象改變了,就把整個對象給我。瀏覽器通過發送請求對象的 ETag 或者 自己所知道的最後修改時間給 WEB 服務器,讓其判斷對象是否改變了。總是跟 Range 頭部一起使用。
Last-Modified:WEB 服務器認爲對象的最後修改時間,比如文件的最後修改時間,動態頁面的最後產生時間等等。
例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
Pragma:主要使用 Pragma: no-cache,相當於 Cache-Control: no-cache。
例如:Pragma:no-cache
Proxy-Authenticate: 代理服務器響應瀏覽器,要求其提供代理身份驗證信息。
Proxy-Authorization:瀏覽器響應代理服務器的身份驗證請求,提供自己的身份信息。
實戰驗證:
1、下載yum包:http://repo.varnish-cache.org
2、使用yum安裝
#yum install ./*.rpm
3、修改配置文件(後端Server-IP:172.16.1.20)
#vim /etc/varnish/default.vcl
修改.host 的ip地址爲172.16.1.20
#vim /etc/sysconfig/varnish
修改監聽端口:
VARNISH_LISTEN_PORT=80
選定存儲方式:VARNISH_STORAGE
設置存儲空間:VARNISH_STORAGE_SIZE
4、啓動服務,使用ss -tnlp查看80端口是否處於堅挺狀態,啓動後端Server
############################################################333
啓動後如何修改vcl
運行過程中如何修改配置文件:
1、進入交互界面
#varnishadm -s ..... -t 127.0.0.1:6082
2、編譯被我們修改後的配置文件
varnish〉vcl.load NAME Change_Name
Change_Name:表示我們需要編譯的文件的文件名
NAME:表示編譯過後叫什麼名字
3、查看編譯後的vcl
varnish〉vcl.list
4、切換到我們要用到的那個vcl
varnish〉vcl.use