Varnish緩存服務區應用

1) Varnish工作流程

    Varnish是一款高性能的開源HTTP加速器

    Varnish與一般服務器軟件類似,分爲master(management)進程和child(worker,主要做cache的工作)進程。master進程讀入命令,進行一些初始化,然後fork並監控child進程。child進程分配若干線程進行工作,主要包括一些管理線程和很多woker線程。

    針對文件緩存部分,master讀入存儲配置(-sfile[,path[,size[,granularity]]]),調用合適的存儲類型,然後創建/讀入相應大小的緩存大文件。接着,master初始化管理該存儲空間的結構體。這些變量都是全局變量,在fork以後會被child進程所繼承(包括文件描述符)。

    在child進程主線程初始化過程中,將前面打開的存儲大文件整個mmap到內存中(如果超出系統的虛擬內存,mmap失敗,進程會減少原來的配置mmap大小,然後繼續mmap),此時創建並初始化空閒存儲結構體,掛到存儲管理結構體,以待分配。

    接着,真正的工作開始,Varnish的某個負責接受新HTTP連接的線程開始等待用戶,如果有新的HTTP連接過來,它總負責接收,然後叫醒某個等待中的線程,並把具體的處理過程交給它。Worker線程讀入HTTP請求的URI,查找已有的object,如果命中則直接返回並回複用戶。如果沒有命中,則需要將所請求的內容,從後端服務器中取過來,存到緩存中,然後再回復。

    分配緩存的過程是這樣的:它根據所讀到object的大小,創建相應大小的緩存文件。爲了讀寫方便,程序會把每個object的大小變爲最接近其大小的內存頁面倍數。然後從現有的空閒存儲結構體中查找,找到最合適的大小的空閒存儲塊,分配給它。如果空閒塊沒有用完,就把多餘的內存另外組成一個空閒存儲塊,掛到管理結構體上。如果緩存已滿,就根據LRU機制,把最舊的object釋放掉。

    釋放緩存的過程是這樣的:有一個超時線程,檢測緩存中所有object的生存期,如果超初設定的TTL(TimeToLive)沒有被訪問,就刪除之,並且釋放相應的結構體及存儲內存。注意釋放時會檢查該存儲內存塊前面或後面的空閒內存塊,如果前面或後面的空閒內存和該釋放內存是連續的,就將它們合併成更大一塊內存。

    整個文件緩存的管理,沒有考慮文件與內存的關係,實際上是將所有的object都考慮是在內存中,如果系統內存不足,系統會自動將其換到swap空間,而不需要varnish程序去控制。

2) varnish的安裝和啓動配置

[root@lab1 varnish]# ls ~/varnish/
3.0.5                                varnish-libs-3.0.4-1.el6.x86_64.rpm
varnish-3.0.4-1.el6.x86_64.rpm       varnish-libs-devel-3.0.4-1.el6.x86_64.rpm
varnish-docs-3.0.4-1.el6.x86_64.rpm
[root@lab1 varnish]# yum install varnish*.rpm
#編輯/etc/sysconfig/varnish,將監聽端口改爲80
VARNISH_LISTEN_PORT=80
#編輯/etc/varnish/default.vcl,將監聽服務器妨礙爲172.16.21.102:80
backend default {
  .host = "172.16.21.102";
  .port = "80";
}
#啓動服務
service varnish start


#此時我們已經可以訪問arnish服務器172.16.21.101了

wps438F.tmp

現在我們可以使用varnishadmin來配置varnish了

[root@node0 varnish]# varnishadm


3) 配置varnish添加X-Cache頭部以判斷緩存是否命中

#拷貝default.vcl到test1.vcl
co default.vcl test1.vcl
#編輯tes1.vcl在sub vcl_deliver段中添加
sub vcl_deliver {
    if(obj.hits>0){ #如果命中次數大於0
        set resp.http.X-Cache = "HIT";
    }else{
        set resp.http.X-Cache = "MISS";
    }
    return (deliver);
}
#加載並啓用test1.vcl
varnish> vcl.load test ./test1.vcl
200       
VCL compiled.
varnish> vcl.use test
200

  

訪問測試,沒有命中

wps43A0.tmp

再次訪問,可以看到已經命中

wps43B0.tmp

4) 配置指定頁面不可以被緩存

再次編輯test1.vcl.添加如下內容

sub vcl_recv {
        if (req.url ~ "miss.html"){  #如果url被miss.html匹配,不要緩存,直接進入pass
                return(pass);
        }
     return (lookup);
}
#加載配置
varnish> vcl.load test2 ./test1.vcl
200       
VCL compiled.
varnish> vcl.use test2
200 
#在102添加miss.html文件
[root@lab2 html]# echo "<h1>Can't be Cached</h1>" > miss.html


訪問miss.html,可見無論如何刷新都不會命中緩存

wps43C1.tmp

5) 設置圖片緩存時間,取消圖片cookie設置

sub vcl_fetch {
        if (req.url ~ "\.(jpg|jpeg|gif|png)"){ #如果文件以指定格式結尾,使其緩存兩個小時
                set beresp.ttl=7200s;
unset beresp.http.Set-Cookie;
        }
}

6) 設置緩存修剪及修剪控制

#修改配置文件
[root@lab1 varnish]# cat /etc/varnish/test1.vcl |grep -v "^#"
backend default {
  .host = "172.16.21.102";
  .port = "80";
}
acl purgers { #訪問控制列表
"127.0.0.1";
"172.16.21.0"/24;
}
sub vcl_recv {
if (req.request == "PURGE"){ #如果請求方法爲PURGE並且
if(! client.ip ~ purgers) {  #客戶端ip不在列表中
error 406 "Method not allowed IN the address"; #生成錯誤報文並退出
}
if (req.url ~ "miss.html"){
return(pass);
}
}
     return (lookup);
}
sub vcl_pass {
if(req.request == "PURGE") {
error 502 " Purge on a passwd object";
}
     return (pass);
}
sub vcl_hit {
if(req.request == "PURGE") {
purge;
error 201 " Purged";
}
     return (deliver);
}
sub vcl_miss {
if(req.request == "PURGE") {
purge;
error 405 " Not Found in Cache";
}
     return (fetch);
}
sub vcl_fetch {
if (req.url ~ "\.(jpg|jpeg|gif|png)"){
set beresp.ttl=7200s;
unset beresp.http.Set-Cookie;
}
}
sub vcl_deliver {
    if(obj.hits>0){
set resp.http.X-Cache = "HIT";
    }else{
set resp.http.X-Cache = "MISS";
    }
    return (deliver);
}
#修剪測試
[root@lab1 varnish]# curl -X PURGE 172.16.21.101
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>201  Purged</title>
  </head>
  <body>
    <h1>Error 201  Purged</h1>
   
Purged

    <h3>Guru Meditation:</h3>
   
XID: 587750580

    <hr>
   
Varnish cache server

  </body>
</html>
[root@lab1 varnish]# curl -X PURGE 172.16.21.101/miss.html
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>502  Purge on a passwd object</title>
  </head>
  <body>
    <h1>Error 502  Purge on a passwd object</h1>
   
Purge on a passwd object

    <h3>Guru Meditation:</h3>
   
XID: 587750582

    <hr>
   
Varnish cache server

  </body>
</html>


7) 設置varnish使用多臺後端主機

#編輯配置文件
[root@lab1 varnish]# cat /etc/varnish/test1.vcl |grep -v "^#"
backend web1 {
  .host = "172.16.21.102";
  .port = "80";
}
backend web2 {
  .host = "172.16.21.103";
  .port = "80";
}
director webservers random {
  .retries = 5;
  {
    .backend = web1;
    .weight = 2 ;
  }
  {
    .backend = web2;
    .weight = 3 ;
  }
}
...
sub vcl_recv {
set req.backend = webservers;
}
     return (lookup);
}
#重新加載並使用
varnish> vcl.load test9 ./test1.vcl
200       
VCL compiled.
varnish> vcl.use test9
200

#訪問測試

wps43C2.tmp

#清除緩存後訪問,

curl -X PURGE 172.16.21.101/

wps43D2.tmp

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章