《高性能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的缓存效果还是很不错的,命中率很高。

相关文章
|
11月前
|
人工智能 JavaScript API
零基础构建MCP服务器:TypeScript/Python双语言实战指南
作为一名深耕技术领域多年的博主摘星,我深刻感受到了MCP(Model Context Protocol)协议在AI生态系统中的革命性意义。MCP作为Anthropic推出的开放标准,正在重新定义AI应用与外部系统的交互方式,它不仅解决了传统API集成的复杂性问题,更为开发者提供了一个统一、安全、高效的连接框架。在过去几个月的实践中,我发现许多开发者对MCP的概念理解透彻,但在实际动手构建MCP服务器时却遇到了各种技术壁垒。从环境配置的细节问题到SDK API的深度理解,从第一个Hello World程序的调试到生产环境的部署优化,每一个环节都可能成为初学者的绊脚石。因此,我决定撰写这篇全面的实
2566 67
零基础构建MCP服务器:TypeScript/Python双语言实战指南
|
8月前
|
弹性计算 人工智能 前端开发
在阿里云ECS上部署n8n自动化工作流:U2实例实战
本文介绍如何在阿里云ECS的u2i/u2a实例上部署开源工作流自动化平台n8n,利用Docker快速搭建并配置定时任务,实现如每日抓取MuleRun新AI Agent并推送通知等自动化流程。内容涵盖环境准备、安全组设置、实战案例与优化建议,助力高效构建低维护成本的自动化系统。
2013 5
|
10月前
|
弹性计算 安全 Linux
阿里云服务器ECS安装宝塔Linux面板、安装网站(新手图文教程)
本教程详解如何在阿里云服务器上安装宝塔Linux面板,涵盖ECS服务器手动安装步骤,包括系统准备、远程连接、安装命令执行、端口开放及LNMP环境部署,手把手引导用户快速搭建网站环境。
|
10月前
|
人工智能 自然语言处理 安全
Python构建MCP服务器:从工具封装到AI集成的全流程实践
MCP协议为AI提供标准化工具调用接口,助力模型高效操作现实世界。
1704 1
|
12月前
|
Linux 网络安全 数据安全/隐私保护
使用Linux系统的mount命令挂载远程服务器的文件夹。
如此一来,你就完成了一次从你的Linux发车站到远程服务器文件夹的有趣旅行。在这个技术之旅中,你既探索了新地方,也学到了如何桥接不同系统之间的距离。
2007 21
|
11月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
1048 13
|
11月前
|
安全
基于Reactor模式的高性能服务器之Acceptor组件(处理连接)
本节介绍了对底层 Socket 进行封装的设计与实现,通过 `Socket` 类隐藏系统调用细节,提供简洁、安全、可读性强的接口。重点包括 `Socket` 类的核心作用(管理 `sockfd_`)、成员函数的功能(如绑定地址、监听、接受连接等),以及 `Acceptor` 组件的职责:监听连接、接收新客户端连接并分发给上层处理。同时说明了 `Acceptor` 与 `EventLoop` 和 `TcpServer` 的协作关系,并展示了其成员变量和关键函数的工作机制。
245 2
|
10月前
|
人工智能 JavaScript 前端开发
用 Go 语言轻松构建 MCP 服务器
本文介绍了使用 Go 语言构建 MCP 服务器的完整过程,涵盖创建服务器实例、注册工具、资源和提示词,以及通过 stdio 和 sse 模式启动服务的方法,帮助开发者快速集成 LLM 应用与外部系统。
|
11月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。