強大的http加速器------varnish

varnish 簡介
css


 

varnish是一款強大的http加速器,其設計初衷由於計算機愈來愈複雜,不像那個只有內存與硬盤的存儲媒介的年代,現在的計算機系統除了內存外還有cpu的L一、L二、L3快取,所以當初的Squid cache自行處理物件替換的架構不可能得知這些狀況而作到最佳,但操做系統能夠得知該狀況,此PoulHenning Kamp設計了varinish的架構


varnish術語解析html


緩存的衡量參數:命中率
#  1 文檔命中率
#  2 字節命中率
緩存類型:
#  私有緩存 (好比客戶端的瀏覽器上的緩存)
#  公共緩存  (好比一個組織機構創建的緩存服務器)
緩存的層次結構
#客戶端 <---...-->2級代理<--------->1級代理 <----------->原始服務器


wKioL1NqDpKwXNyyAABjYlZYI2Q559.jpg


內容路由
#ICP : Internet Cache Protocol 互聯網緩存協議
#CARP: Cache Array Routing Protocol   緩存陣列路由協議---用的比較多



緩存處理客戶端請求的具體步驟
#接受請求
#解析請求  (代理的功能)
#查詢緩存  (檢查本地緩存中是否存在對方請求的內容的副本)
#副本的新鮮度檢測  (檢查本地緩存的副本是否爲最新版本)
#構建響應 (代理的功能---做爲某個應用程序的代理服務器)
#發送
#日誌



保證副本的新鮮度?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
# 文檔過時機制:-----------響應首部
      HTTP/1.0 : Expires (過時時間)
        絕對時間  -----好比2014年5月5日過時                   
      HTTP/1.1 :Cache-Control (max-age=)                                             
        相對時長 ------好比還有100小時可用
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
# 條件式請求: --------------請求首部
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
      1  mtime: If-Modified-Since
         基於時間的條件式請求
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
      2  ETag  :If-None-Match
         基於拓展標籤條件式請求



原始服務器、緩存服務器、客戶端 如何實現對緩存的控制
(1) 原始服務器或緩存服務器控制緩存的能力
# 由原始服務器定義:
  Cache-Control
  Cacmax-age  =(屬於私有緩存中)
     s-maxage =(屬於公共緩存中)
    no-store  :不能緩存
    no-cache :能緩存下來,但不能直接使用此緩存對象;  緩存對象在使用之間必須作 新鮮度驗證
    must-revalidate:必須進行新鮮度驗證
       private     : 客戶端的私有數據,不緩存
         public    : 公共數據,緩存
#原始服務器不添加任何控制機制,而由緩存服務器本身決定緩存時長
(2)客戶端對緩存使用狀況的控制
# 客戶端控制是否使用緩存:
   Cache-Control:
     max-stale:告知緩存機制可使用過時的文件
     no-cache :告知緩存機制必須進行驗證,不然不會接受任何緩存文檔;
     no-store :告知緩存機制必須儘快刪除緩存中的文檔



Varnish 基本架構node


wKiom1NqFFLjxjdNAAEHyOkOcsk016.jpg



如上圖所示:
(1)  varnish主要運行兩個進程: Management進程和Child進程(也叫Cache進程)。
#  Management進程主要實現應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個命令行接口等。Management進程會每隔幾秒鐘探測一下Child進程以判斷其是否正常運行,若是在指定的時長內未獲得Child進程的迴應,Management將會重啓此Child進程。
#  Child進程包含多種類型的線程
#   Accept線程:接收新的鏈接請求並響應;
#   Worker線程:child進程會爲每一個會話啓動一個worker線程,所以,在高併發的場景中可能會出現數百個worker線程甚至更多;
#   Expiry線程:從緩存中清理過時內容;


(2)varnish日誌
 #爲了與系統的其它部分進行交互,Child進程使用了能夠經過文件系統接口進行訪問的共享內存日誌(shared memory log)
 #共享內存日誌大小通常爲80M,其分爲兩部分,前一部分爲計數器,後半部分爲客戶端請求的數據。varnish提供了多個不一樣的工具如varnishlog、varnishncsa或varnishstat等來分析共享內存日誌中的信息並可以以指定的方式進行顯示。



(3)VCL
# Varnish Configuration Language (VCL)是varnish配置緩存策略的工具
# 使用VCL編寫的緩存策略一般保存至.vcl文件中,其須要編譯成二進制的格式後才能由varnish調用
# 整個緩存策略就是由幾個特定的子例程如vcl_recv、vcl_fetch等組成
 VCL語法
# (1)//、#或/* comment */用於註釋
# (2)sub $name 定義函數  ---即定義子例程
# (3)不支持循環,有內置變量
# (4)使用終止語句,沒有返回值
# (5)域專用
# (6)操做符:=(賦值)、==(等值比較)、~(模式匹配)、!(取反)、&&(邏輯與)、||(邏輯或)



(4)varnish後端存儲
# 1)file:使用特定的文件存儲所有的緩存數據;
# 2)malloc:使用malloc()庫調用在varnish啓動時向操做系統申請指定大小的內存空間以存儲緩存對象;
# 3)persistent(experimental):與file的功能相同,但能夠持久存儲數據(即重啓varnish數據時不會被清除);仍處於測試期;



狀態引擎(子例程)linux


  VCL中由多個子例程組成,各個子例程之間有必然的關係,以下圖所示web


wKioL1NqGrvBfwj3AADpIM1wJQk982.jpg


如上圖 pipe  、lookup、pass 爲vcl_recv 子例程的返回狀態。依據此狀態來判斷下一步的去向正則表達式



VCL中的變量vim


wKioL1NqHJrS0XPiAAGBQ89uOcY243.jpg



Varnish的安裝配置後端


  環境搭建瀏覽器


wKioL1NqHpSwceg8AABpALxhjK4080.jpg


如上圖
varnish服務器
172.16.13.2      外網網卡
192.168.20.11    內網網卡
後端服務器兩個
192.168.20.12  服務器一內網地址 
192.168.20.13  服務器二內網地址


 準備工做緩存



1 配置以上三臺服務器的ip地址,此處不作詳解                                
2 server1服務器 編輯web頁面
#vim  /var/www/html/index.html
    <h1>node12.linux.com</h1>
#service httpd start
3  server2服務器 編輯web頁面
#vim  /var/www/html/index.html
    <h1>node13.linux.com</h1>
#service  httpd start


安裝varnish並配置


1)下載3.0版本的varnish
  varnish-3.0.4-1.el6.x86_64.rpm
  varnish-libs-3.0.4-1.el6.x86_64.rpm
  varnish-docs-3.0.4-1.el6.x86_64.rpm
2)安裝
# rpm -ivh varnish*.rpm  安裝以上三個包
# rpm -ql varnish
3)編輯varnish配置文件,定義varnish啓動時的特性
#vim /etc/sysconfig/varnish
   NFILES=131072                         打開的最大文件數
   MEMLOCK=82000                         默認分配給日誌log的內存數82M
   NPROCS="unlimited"                    最大線程數 ,無限制
   RELOAD_VCL=1                          從新啓動服務時候,是否從新編譯vcl 從新使用vcl
   VARNISH_VCL_CONF=/etc/varnish/default.vcl    vcl配置緩存策略的配置文件
   VARNISH_LISTEN_PORT=80                 varnish偵聽的默認端口爲6081,接受用戶請求 ----------通常更改成80端口
   VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1   varnish管理偵聽的地址
   VARNISH_ADMIN_LISTEN_PORT=6082           varnish管理接口,
   VARNISH_SECRET_FILE=/etc/varnish/secret  進入varnish管理接口的密鑰文件
   VARNISH_MIN_THREADS=50    最小線程數                                              
   VARNISH_MAX_THREADS=1000  最大線程數---------varnish超過5000個線程後會不穩定                                        
   VARNISH_THREAD_TIMEOUT=120  空閒線程轉向工做線程的延遲時間
                             VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin  基於文件存儲時的文件路徑 
  VARNISH_STORAGE_SIZE=1G   後端存儲的的大小                                         
  VARNISH_STORAGE="malloc,100M"   自定義內存大小
  VARNISH_TTL=120           請求後端服務器的超時時間  
4)啓動服務
# service varnish start
# ss -ntlp | grep 80



5 ) 進入varnish管理界面
#varnishadm  -S /etc/varnish/secret   -T  127.0.0.1:6082
 varnish> help  --------查看一下全部的命令參數
 200      
help [command]
ping [timestamp]
auth response
quit
banner
status
start
stop
vcl.load <configname> <filename>   加載編譯某個vcl,加載的時候並指定一個配置名稱(該名稱隨意指定)
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname>
vcl.discard <configname>
vcl.list                                  列出全部的vcl
vcl.show <configname>      查看已經列出的vcl
param.show [-l] [<param>]
param.set <param> <value>
panic.show
panic.clear
storage.list



6 )
建立vcl文件
#vim  /etc/varnish/test.vcl   內容以下
backend websrv1 {
  .host = "192.168.20.12";
  .port = "80";
}
進入管理界面編譯使用
#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> vcl.load test2 test.vcl    ------------------加載編譯test.vcl
         200      
         VCL compiled.
varnish> vcl.use test2              -----------------使用已經編譯好 test.vcl 200
varnish> vcl.show test2       ------------------查看test.vcl 的內容
        200      
       backend websrv1 {
         .host = "192.168.20.12";
         .port = "80";
       }


7)客戶端測試


    wKioL1NqKBGwHz1ZAABnK2k4B6c681.jpg




  接下來進行vcl的功能拓展


    1、 判斷上邊的配置是否命中緩存



(1)編輯test.vcl
#vim /etc/varnish/test.vcl
backend websrv1 {
  .host = "192.168.20.12";
  .port = "80";
}
sub vcl_deliver {
  if (obj.hits > 0) {
  set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";
  }
}
(2)管理界面中從新編譯 並使用
# varnish > vcl.load test3 test.vcl
# varnish > vcl.use  test3
 (3)在varnish服務器測試
# curl -I http://172.16.13.2

    wKioL1NqKbfAnVD8AAF9kLbwRU0457.jpg

     命中


   2、判斷從哪一個服務器命中緩存 ---使用變量server.ip



編輯test.vcl
#vim  /etc/varnish/test.vcl
  backend websrv1 {
  .host = "192.168.20.12";
  .port = "80";
 }
  sub vcl_deliver {
  if (obj.hits > 0) {
  set resp.http.X-Cache = "HIT" + server.ip;
  } else {
    set resp.http.X-Cache = "MISS";
   }
 } 
管理界面 從新編譯並使用
#  varnish > vcl.load test4 test.vcl
#  varnish > vcl.use   test4
服務器測試
# curl -I http://172.16.13.2


    wKiom1NqKufRFFdfAAGfKQsrz_s086.jpg


   3、  拒絕使用緩存  ---使用變量req.url



server2服務器再建立一個測試頁面
#vim /var/www/html/test.html
  <h1>test!!!</h1>
編輯vcl配置文件增長vcl_recv子例程      
#vim /etc/varnish/test.vcl
       sub vcl_recv {
        if (req.url ~ "test.html") {
            return(pass);
        }
            return(lookup);
        }
                                                                                                                                                                                                                                                          
varnish服務器測試
# curl -I http://172.16.13.2/test.html


    wKiom1NqK--CsQNFAAE8cJ-7bEM534.jpg

     所有miss,未命中



    4、定義緩存時長



若是客戶端請求的爲圖片文件,就緩存7200s,
若是客戶端請求的爲靜態網頁,就緩存1200s
編輯test.vcl 增長子例程vcl_fetch
#vim  /etc/varnish/test.vcl
        sub vcl_fetch {
           if (req.url ~ "\.(jpg|jpeg|gif|png)$") {
              set beresp.ttl =  7200s;
           }
           if (req.url ~ "\.(html|css|js)$") {
               set beresp.ttl = 1200;
          }
       }
#serivice varnish reload
管理界面從新編輯 並使用
#varnish > vcl.load test6  test.vcl
#varnish > vcl.use   test6



   五 使用PURGE修剪緩存



修剪緩存很是危險,因此咱們必需要作好準備
在具體執行某清理工做時,須要事先肯定以下問題:
#(1)僅須要檢驗一個特定的緩存對象,仍是多個?
#(2)目的是釋放內存空間,仍是僅替換緩存的內容?
#(3)是否是須要很長時間才能完成內容替換?
#(4)這類操做是個平常工做,仍是僅此一次的特殊需求?
移除單個緩存的實現
 #vim  /etc/varnish/test.vcl   增長內容以下
acl purgers {
  "127.0.0.1";
  "172.16.0.0"/16;
}
sub vcl_recv {
  if (req.request == "PURGE") {
    if (!client.ip ~ purgers) {
     error 405 "Method not allowed";
    }
  }
  if (req.url ~ "test.html") {
     return(pass);
  }
  return(lookup);
}
          sub vcl_hit {
  if (req.request == "PURGE") {
     purge;
     error 200 "PURGE OK";
  }
}
sub vcl_miss {
  if (req.request == "PURGE") {
      purge;
      error 404 "Not in cache";
  }
}
sub vcl_pass {
  if (req.request == "PURGE") {
    error 502 "Purged on a passed object";
  }
}
管理界面從新編譯vcl並使用
#varnish > vcl.load test8 vcl.test
#varnish > vcl.use   test8
測試
客戶端在發起HTTP請求時,只須要爲所請求的URL使用PURGE方法便可
使用 curl -I  -X  PURGE  http://varniship/path/to/someurl


    wKiom1NqLdnDJesAAAFE42JZhDQ701.jpg


    6、定義varnish服務器檢測後端服務器健康狀態

   

   

後端服務器爲 192.168.12.12和 192.168.12.13
#vim  /etc/varnish/test.vcl
                                                                                                                                                                     
backend web1 {
  .host = "192.168.20.12";
  .port = "80";
  .probe = {
           .url = "/index.html";
           .interval = 1s;
           .window = 5;
           .threshold = 2;
  }
  }
backend web2 {
  .host = "192.168.20.13";
  .port = "80";
  .probe = {
           .url = "/index.html";
           .interval = 1s;
           .window = 5;
   }        .threshold = 2;
}
director webs random {
  {
    .backend = web1;
    .weight = 2;
  }
  {
     .backend = web2;
     .weight = 1;
  }
}
同時在子例程 vcl_recv 中添加調用req.backend
 set req.backend = webs;   
                                                                                                                                                                     
管理接口從新編譯vcl 並好似用
# varnish >  vcl.load  test9 vcl.test
# varnish > vcl.use  test9


    客戶端測試

    首先關閉192.168.20.12 服務器的httpd服務

         wKioL1NqL1WgpaFBAABa9IuW3nY734.jpg


    啓動192.168.20.12 httpd服務

    wKioL1NqL32D60umAABiNtzZunM216.jpg



   七  將請求的靜態網頁發送至web1服務器

       將請求的圖片發送至web2服務器


   

編輯test.vcl
# vim  /etc/varnish/test.vcl  添加以下內容
     sub vcl_recv {
  if (req.url ~ "\.(html|css|js)$") {
     set req.backend = web1;
  } else {
     set req.backend = web2;
  }
#同時註釋掉director全部內容



   八  如何防盜鏈


   

搜的例子:
if (req.http.referer ~ "http://.*") { 
         if (  !(req.http.referer ~ "http://.*ixdba\.net" 
             || req.http.referer ~ "http://.*google\.com" 
             || req.http.referer ~ "http://.*yahoo\.cn"et 
             || req.http.referer ~ "http://.*google\.cn" 
             )) { 
                 set req.http.host = "www.ixdba.net"; 
                 set req.url = "/templets/default/p_w_picpaths/logo.gif"; 
         } 
                       return (lookup); 
         }


   

varnish經常使用的工具


   

1 varnishstat   查看狀態的命令工具
  用法:
     -1
     -l:列出全部參數
     -f f1,f2 例如 varnishstat -f cache_hit,cache_miss  只查看這兩項
#  須要關注的幾個參數
          cache hit
          cache miss
          client_req
          client_conn
          n_wrk
          n_wrk_create
          n_backend
          n_expired
          n_lru_moved
          s_hdrbytes
          s_bodybytes
2 varnishtop  實時顯示日誌中的信息
    用法:
      -i  tag : 僅顯示指定的tag,如RxHeader
      -I  regexp : 以模式匹配tag對應值;
      -C    :正則表達式匹配時不區分字符大小寫;
3 varnishlog 
  #server  varnishlog start  開啓varnishlog
  #tail  -f /var/log/varnish/varnish.log 
4 varnishreplay  日誌重放工具,用於實現緩存預熱



幾個重要調整的參數


   

# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
# varnish> help
# varnish> param.show  查看全部參數
幾個重要的參數
  thread_pool_add_delay    兩個客戶端建立線程池時的時間間隔
  thread_pool_fail_delay   建立線程池失敗後,第二次建立時的時間間隔
  thread_pool_max          一個線程池中默認裝載的最大的線程數
  thread_poo_min           一個線程池中默認裝載的最小的線程數,限定避免其過於不均衡,防止在繁忙中有的線程池不能少於這個值
  thread_pool_purge_delay   多長時間清理一次線程,     
  thread_pool_timeout       一個線程空閒多長時間 就清除掉
  thread_pool_workspace     一個線程池
  thread_pools              工做線程池的個數
  thread_stats_rate         一批蒐集多少個工做線程的狀態信息
參數調整方法
#  varnish>  param.show  thread_pools
#  varnish>  param.set  thread_pools   3
#  varnish>  param.show  thread_pools

   


思考篇


   緩存命中率低的緣由

緩存空間過小  --------------增大內存,增大磁盤
不存在明顯的熱點數據------------(二八法則:80%的請求落在20%的數據上 )---能夠不用作緩存了,或者將原數據所有作到緩存
源文件更新過於頻繁 -----------建議不要使用緩存了
緩存服務器的可用性  ---------------作分佈式
相關文章
相關標籤/搜索