Varnish 入門
本文將介紹 varnish 的工作流程,安裝以及 varnish 的配置三個方面的內容。首先簡單的介紹 varnish 以及其工作流程,大概了解其內部原理,然后介紹了 varnish 的安裝方法,最后詳細介紹了 varnish 的配置語言 VCL 以及如何對 VCL 進行調試。最后附有一份詳細注釋的 varnish 配置文件代碼。
本文將詳細介紹 varnish 的工作流程、安裝、配置三個方面。相信閱讀完本文,讀者能熟練掌握 varnish。
Varnish 簡介
Varnish 是一款高性能且開源的反向代理服務器和 HTTP 加速器,其采用全新的軟件體系機構,和現在的硬件體系緊密配合,與傳統的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等諸多優點,很多大型的網站都開始嘗試使用 varnish 來替換 squid,這些都促進 varnish 迅速發展起來。
挪威的最大的在線報紙 Verdens Gang(vg.no) 使用 3 臺 Varnish 代替了原來的 12 臺 Squid,性能比以前更好,這是 Varnish 最成功的應用案例。
Varnish 文件緩存的工作流程
Varnish 與一般服務器軟件類似,分為 master 進程和 child 進程。Master 進程讀入存儲配置文件,調用合適的存儲類型,然后創建 / 讀入相應大小的緩存文件,接著 master 初始化管理該存儲空間的結構體,然后 fork 并監控 child 進程。Child 進程在主線程的初始化的過程中,將前面打開的存儲文件整個 mmap 到內存中,此時創建并初始化空閑結構體,掛到存儲管理結構體,以待分配。Child 進程分配若干線程進行工作,主要包括一些管理線程和很多 worker 線程。
接著,開始真正的工作,varnish 的某個負責接收新 HTTP 連接線程開始等待用戶,如果有新的 HTTP 連接過來,它總負責接收,然后喚醒某個等待中的線程,并把具體的處理過程交給它。Worker 線程讀入 HTTP 請求的 URI,查找已有的 object,如果命中則直接返回并回復用戶。如果沒有命中,則需要將所請求的內容,從后端服務器中取過來,存到緩存中,然后再回復。
分配緩存的過程是這樣的:它根據所讀到 object 的大小,創建相應大小的緩存文件。為了讀寫方便,程序會把每個 object 的大小變為最接近其大小的內存頁面倍數。然后從現有的空閑存儲結構體中查找,找到最合適的大小的空閑存儲塊,分配給它。如果空閑塊沒有用完,就把多余的內 存另外組成一個空閑存儲塊,掛到管理結構體上。如果緩存已滿,就根據 LRU 機制,把最舊的 object 釋放掉。
釋放緩存的過程是這樣的:有一個超時線程,檢測緩存中所有 object 的生存期,如果超初設定的 TTL(Time To Live)沒有被訪問,就刪除之,并且釋放相應的結構體及存儲內存。注意釋放時會檢查該存儲內存塊前面或后面的空閑內存塊,如果前面或后面的空閑內存和該 釋放內存是連續的,就將它們合并成更大一塊內存。
整個文件緩存的管理,沒有考慮文件與內存的關系,實際上是將所有的 object 都考慮是在內存中,如果系統內存不足,系統會自動將其換到 swap 空間,而不需要 varnish 程序去控制。
Varnish 安裝
下載 varnish 安裝包
建議下載最新穩定版本(現在最新 varnish 版本為 3.0.2),varnish 提供源代碼安裝包和可執行程序安裝包,按照您的習慣下載適合您平臺的任一安裝包即可。
安裝 varnish
源代碼安裝包安裝
首先安裝 pcre 庫,pcre 庫是為兼容正則表達式,如果不安裝,在安裝 varnish2.0 版本以上時,會提示找不到 pcre 庫。以下是 pcre 的安裝過程,其代碼如清單 1 所示:
清單 1. pcre 庫安裝代碼tar zxvf pcre.tar.gz cd pcre/ ./configure --prefix=/usr/local/pcre/ Make && make install |
</tr>
</tbody>
</table>
tar xzvf varnish-3.0.2.tar.gz cd varnish-3.0.2 export PKG_CONFIG_PATH =/usr/local/pcre/lib/pkgconfig ./configure --prefix=/usr/local/varnish make make install |
</tr>
</tbody>
</table>
rpm -i varnish-2.1.4-2.el5.x86_64.rpm |
</tr>
</tbody>
</table>
varnishd -f /etc/varnish/default.vcl -s file,/var/varnish_cache,1G \ -T 127.0.0.1:2000 -a 0.0.0.0:9082 |
</tr>
</tbody>
</table>
set req.http.X-hit = " hit" "it"; |
</tr>
</tbody>
</table>
backend www { .host = "www.example.com"; .port = "9082"; } |
</tr>
</tbody>
</table>
if (req.http.host ~ "^(www.)?example.com$") { set req.backend = www; } |
</tr>
</tbody>
</table>
backend www { .host = "www.example.com"; .port = "9082"; .probe = { .url = "/test.jpg";// 哪個 url 需要 varnish 請求 .timeout = 1 s;// 等待多長時間超時 .interval = 5s// 檢查的時間間隔 .window = 5;// 維持 5 個 sliding window 的結果 .threshold = 3;// 至少有三次 window 是成功的,就宣告 backend 健康 } } |
</tr>
</tbody>
</table>
Acl local{ "localhost"; "192.0.2.0"/24; !"192.0.2.23";// 除去該 IP } |
</tr>
</tbody>
</table>
公共變量名 | 含義 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
req.backend | 指定對應的后端主機 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
server.ip | 表示服務器 IP | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
client.ip | 表示客戶端 IP | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
req.quest | 只是請求的類型,例如 GET、HEAD 等 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
req.url | 指定請求的地址 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
req.proto | 表示客戶端發起請求的 HTTP 協議版本 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
req.http.header | 表示對應請求中的 HTTP 頭部信息 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
req.restarts | 表示重啟次數,默認最大值為 4 | </tr> </tbody> </table>
公共變量名 | 含義 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
beresp.requset | 指定請求類型,例如 GET、HEAD 等 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||
beresp.url | 表示請求地址 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||
beresp.proto | 表示客戶端發起請求的 HTTP 協議版本 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||
beresp.http.header | 表示對應請求中 HTTP 頭部信息 | </tr>|||||||||||||||||||||||||||||||||||||||||||||||||||||
beresp.ttl | 表示緩存的生存周期,cache 保留時間(s) | </tr> </tbody> </table>
公共變量名 | 含義 | </tr>|||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
obj.status | 返回內容的請求狀態碼,例如 200、302、504 等 | </tr>|||||||||||||||||||||||||||||||||||||
obj.cacheable | 返回的內容是否可以緩存 | </tr>|||||||||||||||||||||||||||||||||||||
obj.valid | 是否有效的 HTTP 請求 | </tr>|||||||||||||||||||||||||||||||||||||
obj.response | 返回內容的請求狀態信息 | </tr>|||||||||||||||||||||||||||||||||||||
obj.proto | 返回內容的 HTTP 版本 | </tr>|||||||||||||||||||||||||||||||||||||
obj.ttl | 返回內容的生存周期,也就是緩存時間,單位秒 | </tr>|||||||||||||||||||||||||||||||||||||
obj.lastuse | 返回上一次請求到現在的時間間隔,單位秒 | </tr> </tbody> </table>
公共變量名稱 | 含義 | </tr>|||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
resp.status | 返回給客戶端的 HTTP 代碼狀態 | </tr>|||||||||||||||||||||||||||
resp.proto | 返回給客戶端的 HTTP 協議版本 | </tr>|||||||||||||||||||||||||||
resp.http.header | 返回給客戶端的 HTTP 頭部消息 | </tr>|||||||||||||||||||||||||||
resp.response | 返回給客戶端的 HTTP 頭部狀態 | </tr> </tbody> </table>
C{
| |