varnish

高性能HTTP加速器Varnish(管理維護篇)

一、varnishd指令
Varnish啓動的命令是/usr/local/varnish/sbin/varnishd,此命令參數較多,用法比較複雜,在命令行執行“/usr/local/varnish/sbin/varnishd –h”即可得到varnishd的詳細用法,表2-6列出了varnishd常用參數的使用方法和含義。
表1

  1. 命令參數 參數含義  
  2. -a address:port 表示varnish對httpd的監聽地址及其端口  
  3. -b address:port 表示後端服務器地址及其端口  
  4. -d 表示使用debug調試模式  
  5. -f file 指定varnish服務器的配置文件  
  6. -p param=value 指定服務器參數,用來優化varnish性能  
  7. -P file Varnish進程PID文件存放路徑  
  8. -n dir 指定varnish的工作目錄  
  9. -s kind[,storageoptions] 指定varnish緩存內容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”。  
  10. 其中“<dir_or_file>”指定緩存文件的存放路徑,“<size>”指定緩存文件的大小  
  11. -t 指定缺省的TTL值  
  12. -T address:port 設定varnish的telnet管理地址及其端口  
  13. -w int[,int[,int]] 設定varnish的工作線程數,常用的方式有:  
  14. -w min,max  
  15. -w min,max,timeout  
  16. 例如:-w5,51200,30,這裏需要說明下,在varnish2.0版本以後,最小啓動的線程數不能設定過大,設置過大,會導致varnish運行異常緩慢。
    -V 顯示varnish版本號和版權信息

二、 配置varnish運行腳本
在安裝varnish一節中,已經將varnish的管理腳本拷貝到了相應的目錄下,這裏稍作修改即可使用,首先修改/etc/sysconfig/varnish文件,根據本章的實例,配置好的文件如下:

  1. NFILES=131072 
  2. MEMLOCK=82000 
  3. DAEMON_OPTS="-a 192.168.12.246:80 \  
  4.              -T 127.0.0.1:3500 \  
  5.              -f /usr/local/varnish/etc/vcl.conf \  
  6.              -u varnish -g varnish \  
  7.              -w 2,51200,10 \  
  8.              -n /data/varnish/cache \  
  9.              -s file, /data/varnish/cache/varnish_cache.data,4G"  

這裏需要說明的是,緩存文件“varnish_cache.data”在32位操作系統下,最大僅能支持2G,如果需要更大緩存文件則需要安裝64爲Linux操作系統。
接着需要修改的文件是/etc/init.d/varnish,找到如下行,改爲相應的路徑即可:

  1. exec="/usr/local/varnish/sbin/varnishd"   
  2. prog="varnishd" 
  3. config="/etc/sysconfig/varnish"    
  4. lockfile="/var/lock/subsys/varnish" 

其中,“exec”用於指定varnishd的路徑,只需修改爲varnish安裝路徑下對應的varnishd文件即可。“config”用於指定varnish守護進程配置文件路徑。
兩個文件修改完畢,就可以授權、運行/etc/init.d/varnish腳本了,執行如下:

  1. [root@varnish-server ~]#chmod 755 /etc/init.d/varnish  
  2. [root@varnish-server ~]#/etc/init.d/varnish   
  3. Usage:/etc/init.d/varnish  
  4. {start|stop|status|restart|condrestart|try-restart|reload|force-reload}  

從輸出可知,此腳本功能強大,可以對varnish進行啓動、關閉、查看狀態、重啓等操作。最後,啓動varnish:

  1. [root@varnish-server ~]# /etc/init.d/varnish  start  
  2. Starting varnish HTTP accelerator:                         [  OK  ]  

 

三、管理varnish運行日誌
varnish是通過內存共享的方式提供日誌的,它提供了兩種日誌輸出形式,分別是:
 通過自帶的varnishlog指令可以獲得varnish詳細的系統運行日誌。
例如:

  1. [root@varnish-server ~]#/usr/local/varnish/bin/varnishlog -n /data/varnish/cache  
  2. 0 CLI          - Rd ping  
  3. 0 CLI          - Wr 200 PONG 1279032175 1.0  
  4. 0 CLI          - Rd ping  
  5. 0 CLI          - Wr 200 PONG 1279032178 1.0  

 通過自帶的varnishncsa指令得到類似apache的combined輸出格式的日誌。
例如:

  1. [root@varnish-server ~]#/usr/local/varnish/bin/varnishncsa  -n  /data/varnish/cache  

也可以將日誌輸出到一個文件中,通過“-w”參數指定即可:

  1. [root@varnish-server ~]#/usr/local/varnish/bin/varnishncsa -n /data/varnish/cache \  
  2. >-w /data/varnish/log/varnish.log  

varnish兩種日誌輸出形式中,第一種在大多數情況下並不是必須的,這裏重點介紹下第二種日誌輸出形式的配置方式。
下面編寫一個名爲varnishncsa的shell腳本,並把此文件放到/etc/init.d目錄下,varnishncsa腳本的完整內容如下所示:

  1. #!/bin/sh  
  2.  
  3. if [ "$1" = "start" ];then  
  4. /usr/local/varnish/bin/varnishncsa -n /data/varnish/cache  -f |/usr/sbin/rotatelogs /data/varnish/log/varnish.%Y.%m.%d.%H.log 3600 480 &  
  5.  
  6. elif [ "$1" = "stop" ];then  
  7.       killall varnishncsa  
  8. else   
  9.                 echo $0 "{start|stop}"  
  10. fi  
  11.  

在這個腳本中,通過管道方式把日誌導入到“rotatelogs”中,而rotatelogs是一個文件分割工具,它可以通過指定時間或者大小等方式來分割日誌文件,這樣就避免了日誌文件過大造成的性能問題。
其中,“3600”是一個小時,也就是每個小時生成一個日誌文件,“480”是一個時區參數,中國是第八時區,相對於UTC相差480分鐘,如果不設置480這個參數,將導致日誌記錄時間和服務器時間相差8小時。關於rotatelogs命令用法,這裏不再詳細講述。
通過對varnish日誌的監控,可以知道varnish的運行狀態和情況。
接着,將此腳本進行授權:

  1. [root@varnish-server ~]#chmod 755 /etc/init.d/varnishncsa  

最後就可以通過如下方式,進行啓動、關閉日誌等操作了:

  1. [root@varnish-server ~]#/etc/init.d/varnishncsa  {start|stop }  

 

四、管理Varnish

1、查看varnish進程
通過上面章節的講解,varnish已經可以啓動起來了,執行如下命令可以查看varnish是否正常啓動:

  1. [root@varnish-server ~]# ps -ef|grep varnish  
  2. root     29615     1  0 00:20 pts/1    00:00:00 /usr/local/varnish/bin/varnishncsa -n /data/varnish/cache -f  
  3. root     29616     1  0 00:20 pts/1    00:00:00 /usr/sbin/rotatelogs /data/varnish/log/varnish.%Y.%m.%d.%H.log 3600 480  
  4. root     29646     1  0 00:21 ?        00:00:00 /usr/local/varnish/sbin/varnishd -P /var/run/varnish.pid -a 192.168.12.246:80 -T 127.0.0.1:3500 -f /usr/local/varnish/etc/vcl.conf -u varnish -g varnish -w 2,51200,10 -n /data/varnish/cache -s file,/data/varnish/cache/varnish_cache.data,4G  
  5. varnish  29647 29646  0 00:21 ?        00:00:00 /usr/local/varnish/sbin/varnishd -P /var/run/varnish.pid -a 192.168.12.246:80 -T 127.0.0.1:3500 -f /usr/local/varnish/etc/vcl.conf -u varnish -g varnish -w 2,51200,10 -n /data/varnish/cache -s file,/data/varnish/cache/varnish_cache.data,4G  

從命令執行結果可知,PID爲29615和29616的進程是varnish的日誌輸出進程,而PID爲29646的進程是varnishd的主進程,並且派生出了一個PID爲29647的子進程。這點跟apache類似。
如果varnish正常啓動的話,80端口和3500端口應該處於監聽狀態,通過如下命令可以查看:

  1. [root@varnish-server ~]# netstat -antl|grep 3500  
  2. tcp        0      0 127.0.0.1:3500              0.0.0.0:*                   LISTEN        
  3. [root@varnish-server ~]#netstat -antl|grep 80    
  4. tcp        0      0 192.168.12.246:80           0.0.0.0:*                   LISTEN        
  5. tcp        1      0 192.168.12.246:41782        192.168.12.26:80            CLOSE_WAIT    

其中,80端口爲varnish的代理端口,3500爲varnish的管理端口。
2、查看varnish緩存效果與狀態
 可以通過瀏覽器訪問對應的網頁,查看varnish緩存的效果,如果varnish緩存成功的話,第二次打開網頁的速度會明顯比第一次快,但是這種方式並不能夠完全說明問題,下面通過命令行方式,通過查看網頁頭來查看命中情況,操作如下:

  1. [root@varnish-server ~]# curl -I http://www.ixdba.net/a/mz/2010/0421/11.html  
  2. HTTP/1.1 200 OK  
  3. Server: Apache/2.2.14 (Unix) PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1  
  4. Last-Modified: Sat, 10 Jul 2010 11:25:15 GMT  
  5. ETag: "5e850b-616d-48b06c6031cc0"  
  6. Content-Type: text/html  
  7. Content-Length: 24941  
  8. Date: Fri, 09 Jul 2010 08:29:16 GMT  
  9. X-Varnish: 1364285597  
  10. Age: 0  
  11. Via: 1.1 varnish  
  12. Connection: keep-alive  
  13. X-Cache: MISS from www.ixdba.net 

  #這裏的"MISS"表示此次訪問沒有從緩存讀取。
再次打開這個頁面,查看網頁頭信息:
 

  1. [root@varnish-server ~]# curl -I http://www.ixdba.net/a/mz/2010/0421/11.html  
  2. HTTP/1.1 200 OK  
  3. Server: Apache/2.2.14 (Unix) PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1  
  4. Last-Modified: Sat, 10 Jul 2010 11:25:15 GMT  
  5. ETag: "5e850b-616d-48b06c6031cc0"  
  6. Content-Type: text/html  
  7. Content-Length: 24941  
  8. Date: Fri, 09 Jul 2010 08:30:35 GMT  
  9. X-Varnish: 1364398612 1364285597  
  10. Age: 79  
  11. Via: 1.1 varnish  
  12. Connection: keep-alive  
  13. X-Cache: HIT from www.ixdba.net   

 #由“HIT”可知,第二次訪問此頁面時,是從緩存中讀取內容了,也就是緩存命中。


緩存命中率的高低直接說明了varnish的運行狀態和效果,較高的緩存命中率說明了varnish運行狀態良好,web服務器的性能也會提高很多,反之,過低的緩存命中率說明varnish的配置可能存在問題,那麼就需要進行調整,因此,從整體上了解varnish的命中率和緩存狀態,對於優化和調整varnish至關重要。
varnish提供了一個varnishstat命令,通過它可以幫我們獲得很多重要的信息。
下面是一個varnish系統的緩存狀態:

  1. [root@varnish-server ~]#/usr/local/varnish/bin/varnishstat  -n /data/varnish/cache  
  2. Hitrate ratio:       10      100      113  
  3. Hitrate avg:     0.9999   0.9964   0.9964  
  4.  
  5.         9990        68.92        49.70 Client connections accepted  
  6.       121820       953.84       606.07 Client requests received  
  7.       112801       919.88       561.20 Cache hits  
  8.           68         0.00         0.34 Cache misses  
  9.         2688        33.96        13.37 Backend conn. success  
  10.         6336         1.00        31.52 Backend conn. reuses  
  11.         2642        33.96        13.14 Backend conn. was closed  
  12.         8978        29.96        44.67 Backend conn. recycles  
  13.         6389         1.00        31.79 Fetch with Length  
  14.         2630        32.96        13.08 Fetch chunked  
  15.          444          .            .   N struct sess_mem  
  16.           23          .            .   N struct sess  
  17.           64          .            .   N struct object  
  18.           78          .            .   N struct objectcore  
  19.           78          .            .   N struct objecthead  
  20.          132          .            .   N struct smf  
  21.            2          .            .   N small free smf  
  22.            3          .            .   N large free smf  
  23.            6          .            .   N struct vbe_conn  
  24.           14          .            .   N worker threads  
  25.           68         1.00         0.34 N worker threads created  
  26.            0         0.00         0.00 N queued work requests  
  27.         1201        11.99         5.98 N overflowed work requests  
  28.            1          .            .   N backends  
  29.            4          .            .   N expired objects    
  30.         3701          .            .   N LRU moved objects  
  31.       118109       942.85       587.61 Objects sent with write  
  32.         9985        71.91        49.68 Total Sessions  
  33.       121820       953.84       606.07 Total Requests  
  34.  

 

這裏需要注意的幾個地方是:
 “Client connections accepted”表示客戶端向反向代理服務器成功發送HTTP請求的總數量。
 "Client requests received"表示到現在爲止,瀏覽器向反向代理服務器發送HTTP請求的累積次數,由於可能會使用長連接,所以這個值一般會大於“Client connections accepted”。
 “Cache hits”表示反向代理服務器在緩存區中查找並且命中緩存的次數。
 “Cache misses”表示直接訪問後端主機的請求數量,也就是非命中數。
 “N struct object”表示當前被緩存的數量。
 “N expired objects”表示過期的緩存內容數量。
 “N LRU moved objects”表示被淘汰的緩存內容個數。


五、管理varnish緩存內容
 Varnish的一個顯著優點是可以靈活的管理緩存內容,而管理緩存主要的工作是如何迅速有效的控制和清除指定的緩存內容,varnish清除緩存相對比較複雜,不過幸運的是,可以通過varnish的管理端口發送PURGE指令來清除不需要的緩存。
下面列出了清除緩存內容的命令格式:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500 purge.url  <regexp>
下面的命令可以列出最近清除的詳細URL列表:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.list 
舉例如下:
(1)如果要清除http://www.example.com/a/2010.html的URL地址,可以執行如下命令:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.url /a/2010.html
(2)批量清除類似http://www.example.com/a/b/s*.html的URL地址,可執行如下命令:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.url ^/a/b/s.*$
(3)批量清除類似http://www.example.com/a/b/*.html的URL地址,可執行如下命令:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.url  ^/a/b.*$
(4)如果要清除所有緩存,可執行如下命令:
/usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500 purge.url  ^.*$
(5)查看最近清除的詳細URL列表
[root@varnish-server ~]# /usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500 purge.list
0x2dc310c0 1278674980.497631     0      req.url ~ /zm/a/web/2010/0423/64.html
0x2dc31100 1278674964.851327     1      req.url ~ ^/zm/a/d.*$
除了通過linux命令行方式清理varnish緩存外,還可以通過telnet到管理端口的方式來清理緩存頁面,例如:

  1. [root@varnish-server ~]#telnet 192.168.12.246 3500                 
  2. Trying 192.168.12.246...  
  3. Connected to localhost.localdomain (192.168.12.246).  
  4. Escape character is '^]'.  
  5. 200 154       
  6. -----------------------------  
  7. Varnish HTTP accelerator CLI.  
  8. -----------------------------  
  9. Type 'help' for command list.  
  10. Type 'quit' to close CLI session.  
  11.  
  12. purge.url  /a/mz/2010/0421/11.html  #這裏是清除這個頁面緩存  
  13. 200 0         
  14.  
  15. purge.url  ^/zm/a/d.*$   #這裏是清除/zm/a/d/目錄下所有以字母d開頭的緩存頁面  
  16. 200 0  
  17.  

對於系統管理人員或者運維人員來說,時刻了解varnish命中率是至關重要的,雖然varnish給出了很詳細的統計數據,但是統計的數據不是很直觀,並且必須登錄到varnish服務器才能查看,下面給出一個php程序,可以隨時隨地,並且非常清晰的瞭解varnish系統的命中率相關情況,程序如下:

  1. <?php 
  2.  
  3. // This is just a code snippet written by Jason "Foxdie" Gaunt, its not meant to be executed, it may work as-is, it may not.  
  4. // I freely acknowledge this code is unoptimised but it has worked in practice for 6 months :)  
  5.  
  6. // Lets define our connection details  
  7. $adminHost = "127.0.0.1"; // varnish服務器的IP地址  
  8. $adminPort = "3500"; // varnish服務器管理端口  
  9.  
  10. // pollServer(str) - this function connects to the management port, sends the command and returns the results, or an error on failure  
  11. function pollServer($command) {  
  12.  global $adminHost, $adminPort;  
  13.    
  14.  $socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname("tcp"));  
  15.  if ((!socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, Array("sec" => "5", "usec" => "0"))) OR (!socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, Array("sec" => "5", "usec" => "0"))))  {  
  16.   die("Unable to set socket timeout");  
  17.  }  
  18.    
  19.  if (@socket_connect($socket, $adminHost, $adminPort)) {  
  20.   $data = "";  
  21.       
  22.   if (!$socket) {  
  23.    die("Unable to open socket to " . $server . ":" . $port . "\n");  
  24.   }  
  25.     
  26.   socket_write($socket, $command . "\n");  
  27.   socket_recv($socket, $buffer, 65536, 0);  
  28.   $data .= $buffer;    
  29.     
  30.   socket_close($socket);  
  31.     
  32.   return $data;  
  33.  }  
  34.  else {  
  35.   return "Unable to connect: " . socket_strerror(socket_last_error()) . "\n";  
  36.  }  
  37. }  
  38.  
  39. // byteReduce(str) - this function converts a numeric value of bytes to a human readable format and returns the result  
  40. function byteReduce($bytes) {  
  41.  // Terabytes  
  42.  if ($bytes > 1099511627776) {  
  43.   return round($bytes / 1099511627776) . "TB";  
  44.  }  
  45.  else if ($bytes > 1073741824) {  
  46.   return round($bytes / 1073741824) . "GB";  
  47.  }  
  48.  else if ($bytes > 1048576) {  
  49.   return round($bytes / 1048576) . "MB";  
  50.  }  
  51.  else if ($bytes > 1024) {  
  52.   return round($bytes / 1024) . "KB";  
  53.  }  
  54.  else {  
  55.   return $bytes . "B";  
  56.  }  
  57. }  
  58.  
  59. // This is where our main code starts  
  60. echo "<div class=\"inner\"><br />Statistics since last reset:<ul>";  
  61. $stats = pollServer("stats");  
  62. if (substr($stats, 0, 3) == "200") { // If request was legitimate  
  63.  // Clear all excessive white space and split by lines  
  64.  $stats = preg_replace("/ {2,}/", "|", $stats);   
  65.  $stats = preg_replace("/\n\|/", "\n", $stats);  
  66.  $statsArray = explode("\n", $stats);  
  67.    
  68.  // Removes the first call return value and splits by pipe  
  69.  array_shift($statsArray);  
  70.  $statistics = array();  
  71.  foreach ($statsArray as $stat) {  
  72.   @$statVal = explode("|", $stat);  
  73.   @$statistics[$statVal[1]] = $statVal[0];  
  74.  }  
  75.  unset($stats, $statsArray, $stat, $statVal);  
  76.    
  77.  // Start outputting statistics  
  78.  echo "<li>" . $statistics["Client connections accepted"] . " clients served over " . $statistics["Client requests received"] . " requests";  
  79.  echo "<li>" . round(($statistics["Cache hits"] / $statistics["Client requests received"]) * 100) . "% of requests served from cache";  
  80.  echo "<li>" . byteReduce($statistics["Total header bytes"] + $statistics["Total body bytes"]) . " served (" . byteReduce($statistics["Total header bytes"]) . " headers, " . byteReduce($statistics["Total body bytes"]) . " content)";  
  81.    
  82.  // The following line is commented out because it only works when using file storage, I switched to malloc and this broke  
  83.  // echo "<li>" . byteReduce($statistics["bytes allocated"]) . " out of " . byteReduce($statistics["bytes allocated"] + $statistics["bytes free"]) . " used (" . round(($statistics["bytes allocated"] / ($statistics["bytes allocated"] + $statistics["bytes free"])) * 100) . "% usage)";  
  84. }  
  85. else {  
  86.  echo "Unable to get stats, error was: \"" . $stats;  
  87. }  
  88.  
  89. echo "</ul></div>";  
  90.  
  91. ?> 
  92.  

將此php程序放到varnish服務器上,即可統計處當前varnish的命中率以及緩存狀態,統計結果類似於下面的一個輸出:

  1. Statistics since last reset:  
  2.  63543 clients served over 584435 requests  
  3.  98% of requests served from cache  
  4.  4GB served (246MB headers, 4GB content)  

在這個輸出中,清晰的列出了瀏覽器請求總數、緩存命中率、緩存區中所有緩存內容的HTTP頭信息長度和緩存內容的正文長度。根據這個結果判斷,varnish的緩存效果還是很不錯的,命中率很高。


轉自:http://www.cnblogs.com/littlehb/archive/2012/02/12/2347768.html

發佈了66 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章