Varnish配置

3章 Varnish
一、Varnish概述
2.1.1 Varnish的結構與特點
 Varnish是一個輕量級別的Cache和反向代理軟件,先進的設計理念和成熟的設計框架是Varnish的主要特點:
       基於內存進行緩存,重啓後數據將消失
       利用虛擬內存方式,I/O性能好.
       支持設置0~60秒的精確緩存時間
       VCL配置管理比較靈活
       32位機器上緩存文件大小爲最大2GB
       具有強大的管理功能,例如:top stat admin list等
       狀態設計巧妙,結構清晰
       利用二叉堆管理緩存文件,達到可以積極刪除目的。


2.1.2 Varnish與Squid的對比
  說到Varnish,就不能不提Squid,Squid是一個高性能的代理緩存服務器,它和Varnish的相比較有諸多的異同點,下面進行分析:
        相同點:
       都是一個反向代理服務器
       都是開源軟件
     
        異同點,也是Varnish的優點:
       Varnish的穩定性很高,兩者在完成相同的負荷的工作時,Squid發生的故障機率要高於Varnish,因爲Squid需經常重啓.
       Varnish訪問速度更快,Varnish採用用了”Visual Page Cache”技術,所有緩存的數據都直接從內存讀取,而且Squid是從硬盤讀取緩存數據,因此Varnish訪問速度更快
       Varnish可以支持更多的併發連接,因爲Varnish的TCP連接要比Squid釋放快,所以在高併發連接情況可以支持更多地TCP連接。
       Varnish可以通過管理端口,使用正則表達式清除部分緩存,而Squid做不到。
     Varnish缺點如下:
       在高併發狀態下CPU,I/O和內存等資源開銷都要高於Squid。
       Varnish進程一旦掛起,崩潰或者重啓,緩存數據都會從內存當中完全釋放,此時所有的請求會發送後端的WEB服務器,在高併發的情況下,這會給後端的服務器造成很大壓力。


  Internet外網
      |
  ---FW-->防火牆
      |
      |
      |
      |
--Varnish1  --Varnish2  --Varnish3
   |            |            |
   |            |            |
   |            |            |
   |            |            | 
 WEB1          WEB2         WEB3


二、Varnish安裝
2.1、環境:
Varnish-server:10.0.0.202
Nginx-Server:10.0.0.201


2.2.2、創建Varnish用戶緩存目錄和日誌
# useradd varnish -s /sbin/nologin   創建varnish用戶
# mkdir /varnish/cache –p         創建varnish緩存目錄
# mkdir /varnish/log              創建varnish日誌 
# chown -R varnish:varnish /varnish/  修改賦權組




2.2.3、安裝PCRE 
爲了兼容正則表達式,編譯 2.0以上版本時否則會報錯pcre找不到。
# yum install gcc 
# yum install gcc-c++ libstdc++-devel
# yum install -y httpd-devel pcre perl pcre-devel zlib zlib-devel GeoIP GeoIP-devel
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.34.tar.bz2
# tar -xvf pcre-8.34.tar.bz2
# cd pcre-8.34/
# ./configure --prefix=/usr/local/prce/
# make && make install


2.2.4、安裝Varnish
# wget http://repo.varnish-cache.org/source/varnish-3.0.0.tar.gz
# tar -xzvf varnish-3.0.0.tar.gz
# cd varnish-3.0.0
#./configure --prefix=/usr/local/varnish PKG_CONFIG_PATH=/usr/lib/pkgconfig
# make && make install
# cd /usr/local/varnish/sbin
./varnishd -V




2.3.1、VCL使用說明
VCL,即Varnish Configaution Language 用來定義Varnish的存儲策略
VCL內置函數
   (1)、vcl_recv函數
用於接收和處理請求,當請求到達併成功接收後被調用.
    函數一般以如下幾個關鍵字結束
pass表示進入pass模式,把請求控制權交給vcl_pass函數
pige 表示進入pige模式,把請求控制權交給vcl_pipe函數
error code[reason] 表示返回”code”給客戶,並放棄處理該請求,”code”是錯誤的標識
,例如:200和405等,”reason”是錯誤信息


(2)、vcl_pipe函數
   此函數在進入pipe模式時被調用,用於請求直接傳至後端主機,在請求和返回內容沒有改變的情況下,將不變的內容返回給客戶端,直到這個連接被關閉。
   此函數一般以如下幾個關鍵字結束:
     error code[reason]
     pipe
(3)、vcl_pass函數
   此函數在進入pass模式時被調用,用於請求直接傳至後端主機,後端主機但應數據,將答應的數據傳至客戶端,但不進行任何緩存,當前連接下每次都返回最新的內容。
此函數一般以如下幾個關鍵字結束:
error code[reason]
     pass


(4)、lookup函數
   表示在緩存中查找被請求的對象,並且根據查找的結果把控制權交給vcl_hit或者函數vcl_miss


(5)、vcl_hit函數
在執行lookup指令後,在緩存中找到請求的內容後將自動調用該函數
此函數一般以如下幾個關鍵字結束:
fetch 表示從後端獲取請求的內容,並且把控制權交給vcl_fetch函數
  deliver  表示將找到的內容發送給客戶,並且把控制權交給函數vcl_deliver
error code[reason]
pass


(6)、vcl_miss函數
   在執行lookup指令後,在緩存中沒有找到請求的內容時自動調用該方法,此函數可以於判斷是否需要從後端服務器獲取內容
  此函數一般以如下幾個關鍵字結束:
fetch:表示從後端獲取請求內容,並且把控制權交給vcl_fetch函數
error code[reason]
pass


(7)、vcl_miss函數
在後端主機更新緩存並且獲取內容後調用該方法,接着,通過判斷獲取的內容來決定是將內容放入緩存,還是直接返回給客戶端,
   此函數一般以如下幾個關鍵字結束:
 error code[reason]
pass
deliver 


(8)、vcl_deliver函數
  將在緩存中找到請求的內容發送給客戶端調用此方法。
此函數一般以如下幾個關鍵字結束:
error code[reason]
deliver 


(9)、vcl_timeout函數
 在緩存內容到期前調用此函數.
此函數一般以如下幾個關鍵字結束:
 discard:表示從緩存中清除內容
 fetch


(10)、vcl_discard函數
  在緩存內容到期後或者緩存空間不足時,自動調用該函數.
此函數一般以如下幾個關鍵字結束:
  keep:表示將內容繼續保留在緩存當中
discard 




三、Varnish配置
2.3.2、配置Varnish配置實戰
由於本版不同,Varnish配置文件的寫法也存在一定的差異,Varnish3.x版本不但在配置寫法上和2.x版本不同,修復了很多不應用BUG,本文以3.x版本爲基準
   Varnish安裝完成後,默認的配置文件/usr/local/varnish/etc/varnish/default.vcl
 此配置文件默認是全部註釋掉的.配置文件如下:
先編輯配置文件
# vi /usr/local/varnish/etc/varnish/default.vcl
# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.

# Default backend definition.  Set this to point to your content
# server.



# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
#設置後端WEB服務-關注點
backend webtest1 {
    .host = "10.0.0.201";
    .port = "80";
    .connect_timeout = 1s;
    .first_byte_timeout = 5s;
    .between_bytes_timeout = 2s;
}


#可以定義多臺WEB-關注點
#backend webtest2 {
#    .host = "192.168.100.6";
#    .port = "80";
#    .connect_timeout = 1s;
#    .first_byte_timeout = 5s;
#    .between_bytes_timeout = 2s;
#}
#多臺WEB可以定義負載均衡-關注點lb_test,
#director lb_test random {
#    {
#      .backend = webtest1;
#      .weight = 5;
    # }
    # {
    #   .backend = webtest2;
    #   .weight = 5;
    # }
#}
#定義那些IP或者IP段具有訪問權-關注點
acl purge {
    "localhost";
    "127.0.0.1";
    "192.168.1.0"/24;
    "10.0.0.0"/16;
}




sub vcl_recv {
#開啓壓縮模式,圖片格式取消壓縮
if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|png|gif|jpeg|flv)" ) {
        remove req.http.Accept-Encoding;
        remove req.http.Cookie;
    } else if (req.http.Accept-Encoding ~ "gzip") {
        set req.http.Accept-Encoding = "gzip";
    } else if (req.http.Accept-Encoding ~ "deflate") {
        set req.http.Accept-Encoding = "deflate";
    } else {
        remove req.http.Accept-Encoding;
    }
}
#根據host設置後端服務器-關注點
  if (req.http.Host ~ "(?i)(www.test1.com|www.test2.com|10.0.0.202)") {
     #set req.backend = lb_test; #如果開啓負載用此項,上面的負載均衡的POOL的名叫注意:lb_test
     set req.backend = webtest1;
       }else
  if (req.http.Host ~ "(?i)image.wdj.com"){
     set req.backend = webtest1;
  }else
  {
    error 408 "Hostname not found";
  }
#如果爲purge請求,客戶端ip不在訪問列表中,返回405拒絕-關注點 
  if (req.request == "PURGE") {
     if (!client.ip ~purge) {
       error 405 "Not Allowed";
   }
#本地緩存查找
   return(lookup);
  }
#如果爲GET請求,url後綴爲jpg,png,gif等 取出cookie
  if (req.request == "GET"&&req.url ~ "(?i)\.(jpg|png|gif|swf|jpeg|ico)$") {
        unset req.http.cookie;
  }
#如果GET請求,url爲php,則穿過cache,不緩存
  if (req.request =="GET"&&req.url ~ "(?i)\.php($|\?)"){
        return (pass);
  }
#簡單防盜鏈--關注點
if (req.http.referer ~ "http://.*") {
  if ( !(req.http.referer ~ "http://.*test1\.com"
     || req.http.referer ~ "http://.*test2\.com"
     || req.http.referer ~ "http://.*wdj\.com"
     || req.http.referer ~ "http://.*google\.com"
     || req.http.referer ~ "http://.*baidu\.com"
     || req.http.referer ~ "http://.*yahoo\.cn"
  )) {
      error 404 "Not Found!";
 }
}
#獲取客戶端ip
#     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;
        }
#   }
#不是以下請求進入pipe模塊
    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
#不是GET 和HEAD請求不緩存
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization) {
        /* Not cacheable by default */
        return (pass);
    }
    return (lookup);
}
#
 sub vcl_pipe {
     return (pipe);
 }
#
sub vcl_pass {
    return (pass);
}
#使用url+host hash算法查找數據
sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return (hash);
}
# 如果請求爲purge 將清除緩存
sub vcl_hit {
   if (req.request == "PURGE") {
       set obj.ttl = 0s;
       error 200 "Purged";
    }
    return (deliver);
}


sub vcl_miss {
    return (fetch);
}
#
sub vcl_fetch {
    if (beresp.ttl <= 0s ||
        beresp.http.Set-Cookie ||
        beresp.http.Vary == "*") {
                /*
                 * Mark as "Hit-For-Pass" for the next 2 minutes
                 */
                set beresp.ttl = 0 s;
                return (hit_for_pass);
    }
    if (beresp.http.Pragma ~"no-cache" ||
    beresp.http.Cache-Control ~"no-cache" ||
    beresp.http.Cache-Control ~"private") {
      return (deliver);
   }
#爲特定格式文件設置緩存時間,有多種格式可以直接在後面加-關注點
    if (req.request == "GET"&&req.url ~ "(?i)\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$") {
    set beresp.ttl = 30d;
  }
   if (req.request == "GET"&&req.url ~ "(?i)\.(html|htm)$") {
    set beresp.ttl = 1d;
  }
    return (deliver);
}
# 設置返回狀態
 sub vcl_deliver {
     set resp.http.x-hits = obj.hits;
     if (obj.hits > 0) {
      set resp.http.X-Cache = "Hit test.com";
   }else {
       set resp.http.X-Cache = "Miss test.com";
   }
     set resp.http.Server = "BWM";
     return (deliver);
 }
# 定義錯誤
sub vcl_error {
    set obj.http.Content-Type = "text/html; charset=utf-8";
    set obj.http.Retry-After = "5";
    synthetic {"
<?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>"} + obj.status + " " + obj.response + {"</title>
  </head>
  <body>
    <h1>Error "} + obj.status + " " + obj.response + {"</h1>
    <p>"} + obj.response + {"</p>
    <h3>Guru Meditation:</h3>
    <p>XID: "} + req.xid + {"</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>
"};
    return (deliver);
}


sub vcl_init {
        return (ok);
}


sub vcl_fini {
        return (ok);
}


四、Varnish運行
-u 以什麼用運行
-g 以什麼組運行
-f varnish配置文件
-a 綁定IP和端口
-s varnish緩存文件位置與大小
-w 最小,最大線程和超時時間
-t 緩存時間s
-T varnish管理端口,主要用來清除緩存
-p client_http11=on 支持http1.1協議
-P(大P) /usr/local/varnish/var/varnish.pid 指定其進程碼文件的位置,實現管理
停止varnish


/usr/local/varnish/sbin/varnishd -u varnish -g varnish -f /usr/local/varnish/etc/varnish/default.vcl -a 10.0.0.202:80 -s file,/varnish/cache/varnish_cache.data,1G -w 1024,51200,10 -t 3600 -T 10.0.0.202:3000                  
企業裏裏面開啓爲100G


2.4.2、啓動日誌
# /usr/local/varnish/bin/varnishncsa -w  /varnish/log/varnish.log &


日誌加入開機啓動:
 echo "/usr/local/varnish/bin/varnishncsa -w /data/varnish/logs/varnish.log &" >> /etc/rc.local
參數: -w 指定varnish訪問日誌要寫入的目錄與文件
發佈了129 篇原創文章 · 獲贊 58 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章