《高性能Linux服务器构建实战》——2.5节管理Varnish-阿里云开发者社区

开发者社区> 华章出版社> 正文

《高性能Linux服务器构建实战》——2.5节管理Varnish

简介: 本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第2章,第2.5节管理Varnish,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看

2.5 管理Varnish

2.5.1 查看Varnish进程
通过上一节的设置,Varnish已经可以启动起来了。执行如下命令可以查看Varnish是否正常启动。

[root@varnish-server ~]# ps -ef|grep varnish
root 29615 1 0 00:20 pts/1 00:00:00 /usr/local/varnish/bin/varnishncsa -n /data/varnish/cache -f
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
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
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端口应该处于监听状态,这一点通过如下命令可以查看。

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

其中,80端口为Varnish的代理端口,3500为Varnish的管理端口。
2.5.2 查看Varnish缓存效果与状态
可以通过浏览器访问对应的网页来查看Varnish缓存的效果。如果Varnish缓存成功,第二次打开网页的速度会明显比第一次快,但是这种方式并不能够充分说明问题。下面用命令行方式,通过查看网页头来查看命中情况。

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

X-Cache: MISS from www.ixdba.net #这里的“MISS”表示此次访问没有从缓存读取
再次打开这个页面,查看网页的头信息。

[root@varnish-server ~]# curl -I http://www.ixdba.net/a/mz/2010/0421/11.html
HTTP/1.1 200 OK
Server: Apache/2.2.14 (Unix) PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1
Last-Modified: Sat, 10 Jul 2010 11:25:15 GMT
ETag: "5e850b-616d-48b06c6031cc0"
Content-Type: text/html
Content-Length: 24941
Date: Fri, 09 Jul 2010 08:30:35 GMT
X-Varnish: 1364398612 1364285597
Age: 79
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT from www.ixdba.net      #由“HIT”可知,第二次访问此页面时,从缓存中读取内容,也就是缓存命中

缓存命中率的高低直接说明了Varnish的运行状态和效果,较高的缓存命中率说明Varnish运行状态良好,Web服务器的性能也会提高很多;反之,过低的缓存命中率说明Varnish的配置可能存在问题,需要进行调整。因此,从整体上了解Varnish的命中率和缓存状态,对于优化和调整Varnish至关重要。
Varnish提供了一个varnishstat命令,通过它可以获得很多重要的信息。
下面是一个Varnish系统的缓存状态:

[root@varnish-server ~]#/usr/local/varnish/bin/varnishstat  -n /data/varnish/cache
Hitrate ratio:       10      100      113
Hitrate avg:     0.9999   0.9964   0.9964

        9990        68.92        49.70 Client connections accepted
      121820       953.84       606.07 Client requests received
      112801       919.88       561.20 Cache hits
          68         0.00         0.34 Cache misses
        2688        33.96        13.37 Backend conn. success
        6336         1.00        31.52 Backend conn. reuses
        2642        33.96        13.14 Backend conn. was closed
        8978        29.96        44.67 Backend conn. recycles
        6389         1.00        31.79 Fetch with Length
        2630        32.96        13.08 Fetch chunked
         444          .            .   N struct sess_mem
          23          .            .   N struct sess
          64          .            .   N struct object
          78          .            .   N struct objectcore
          78          .            .   N struct objecthead
         132          .            .   N struct smf
           2          .            .   N small free smf
           3          .            .   N large free smf
           6          .            .   N struct vbe_conn
          14          .            .   N worker threads
          68         1.00         0.34 N worker threads created
           0         0.00         0.00 N queued work requests
        1201        11.99         5.98 N overflowed work requests
           1          .            .   N backends
           4          .            .   N expired objects  
        3701          .            .   N LRU moved objects
      118109       942.85       587.61 Objects sent with write
        9985        71.91        49.68 Total Sessions
      121820       953.84       606.07 Total Requests

这里需要注意以下几点:
“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”表示被淘汰的缓存内容个数。

2.5.3 通过端口管理Varnish
Varnish提供了基于端口的管理方式,用户可以通过telnet方式登录到管理端口,对Varnish子进程进行启动、关闭、查看状态和清除缓存等操作。具体的使用方式如下:

[root@varnish-server ~]#telnet 192.168.12.246 3500               
Trying 192.168.12.246...
Connected to localhost.localdomain (192.168.12.246).
Escape character is '^]'.
200 154     
-----------------------------
Varnish HTTP accelerator CLI.
-----------------------------
Type 'help' for command list.
Type 'quit' to close CLI session.

help                  #在这里输入“help”即可得到如下帮助信息
200 377     
help [command]
ping [timestamp]  
auth response  
quit
banner
status                #显示服务运行状态
start                #启动Varnish的子服务
stop                #关闭Varnish的子服务
stats                #显示服务的全部状态
vcl.load <configname> <filename>     #操作VCL配置文件的相关操作,如果要修改VCL文件,首先
                                 #要通过vcl.load载入一个配置,然后执行vcl.use配置
vcl.inline <configname> <quoted_VCLstring>  
vcl.use <configname>        #载入指定的配置文件
vcl.discard <configname>         #丢弃指定的VCL配置文件
vcl.list                        #显示当前载入的VCL配置文件信息
vcl.show <configname>           #可以显示某个VCL文件的内容
param.show [-l] [<param>]       #用于显示程序的运行参数
param.set <param> <value>       #用于动态更改某个运行参数
purge.url <regexp>              #用来清除指定规则的url缓存
purge <field> <operator> <arg> [&& <field> <oper> <arg>]...
purge.list                      #列出执行过的规则列表

这里列举一个简单的操作示例,执行如下:

[root@varnish-server ~]#telnet 192.168.12.246 3500               
Trying 192.168.12.246...
Connected to localhost.localdomain (192.168.12.246).
Escape character is '^]'.
200 154     
-----------------------------
Varnish HTTP accelerator CLI.
-----------------------------
Type 'help' for command list.
Type 'quit' to close CLI session.

stop                   #这里表示关闭varnishd的子进程
200 0       

Start                   #这里表示重新启动varnishd的子进程
200 0       

Status                #查看varnishd的运行状态
200 22      
Child in state running

2.5.4 管理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 
下面举例介绍如何管理Varnish缓存内容。
 如果要清除http://www.example.com/a/2010.html的URL地址,可执行如下命令:
 /usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.url /a/2010.html
 批量清除类似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.*$
 批量清除类似http://www.example.com/a/b/*.html的URL地址,可执行如下命令:
 /usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500  purge.url^/a/b.*$
 如果要清除所有缓存,可执行如下命令:
 /usr/local/varnish/bin/varnishadm -T 192.168.12.246:3500 purge.url^.*$
 查看最近清除的详细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到管理端口的方式来清理缓存页面,例如:

[root@varnish-server ~]#telnet 192.168.12.246 3500               
Trying 192.168.12.246...
Connected to localhost.localdomain (192.168.12.246).
Escape character is '^]'.
200 154     
-----------------------------
Varnish HTTP accelerator CLI.
-----------------------------
Type 'help' for command list.
Type 'quit' to close CLI session.

purge.url  /a/mz/2010/0421/11.html  #这里清除这个页面缓存
200 0       

purge.url  ^/zm/a/d.*$   #这里清除/zm/a/目录下所有以字母d开头的缓存页面
200 0

对于系统管理人员或运维人员来说,时刻了解Varnish命中率是非常重要的。虽然Varnish给出了很详细的统计数据,但是这些统计数据不是很直观,并且必须登录到Varnish服务器才能查看。下面给出一个PHP程序,可以随时随地清晰地了解Varnish系统的命中率的相关情况。

<?php

$adminHost = "127.0.0.1"; //Varnish服务器的IP地址
$adminPort = "3500"; // Varnish服务器管理端口

returns the results, or an error on failure
function pollServer($command) {
    global $adminHost, $adminPort;
    
    $socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname("tcp"));
    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"))))  {
        die("Unable to set socket timeout");
    }
    
    if (@socket_connect($socket, $adminHost, $adminPort)) {
        $data = "";
                
        if (!$socket) {
            die("Unable to open socket to " . $server . ":" . $port . "\n");
        }
        
        socket_write($socket, $command . "\n");
        socket_recv($socket, $buffer, 65536, 0);
        $data .= $buffer;        
        
        socket_close($socket);
        
        return $data;
    }
    else {
        return "Unable to connect: " . socket_strerror(socket_last_error()) . "\n";
    }
}

function byteReduce($bytes) {
    if ($bytes > 1099511627776) {
        return round($bytes / 1099511627776) . "TB";
    }
    else if ($bytes > 1073741824) {
        return round($bytes / 1073741824) . "GB";
    }
    else if ($bytes > 1048576) {
        return round($bytes / 1048576) . "MB";
    }
    else if ($bytes > 1024) {
        return round($bytes / 1024) . "KB";
    }
    else {
        return $bytes . "B";
    }
}

echo "<div class=\"inner\"><br />Statistics since last reset:<ul>";
$stats = pollServer("stats");
if (substr($stats, 0, 3) == "200") {
       $stats = preg_replace("/ {2,}/", "|", $stats); 
       $stats = preg_replace("/\n\|/", "\n", $stats);
       $statsArray = explode("\n", $stats);
    
    array_shift($statsArray);
    $statistics = array();
    foreach ($statsArray as $stat) {
        @$statVal = explode("|", $stat);
        @$statistics[$statVal[1]] = $statVal[0];
    }
    unset($stats, $statsArray, $stat, $statVal);
    
    echo "<li>" . $statistics["Client connections accepted"] . " clients served over " . $statistics["Client requests received"] . " requests";
    echo "<li>" . round(($statistics["Cache hits"] / $statistics["Client requests received"]) * 100) . "% of requests served from cache";
    echo "<li>" . byteReduce($statistics["Total header bytes"] + $statistics["Total body bytes"]) . " served (" . byteReduce($statistics["Total header bytes"]) . " headers, " . byteReduce($statistics["Total body bytes"]) . " content)";
    
    // 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)";
}
else {
    echo "Unable to get stats, error was: \"" . $stats;
}

echo "</ul></div>";

?>

将此PHP程序放到Varnish服务器上,即可统计出当前Varnish的命中率及缓存状态。统计结果类似于如下的一个输出:

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

在这个输出中,清晰地列出了浏览器的请求总数、缓存命中率、缓存区中所有缓存内容的HTTP头信息长度和缓存内容的正文长度。根据这个结果判断,Varnish的缓存效果还是很不错的,命中率很高。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接