RH358优化Web服务器流量–使用Varnish缓存静态网页
本章节介绍如何部署和使用缓存服务Varnish,相当于CDN的形式加快访问。
RH358专栏地址:https://blog.csdn.net/qq_41765918/category_11532281.html
文章目录
-
- RH358优化Web服务器流量--使用Varnish缓存静态网页
-
- 1. 描述 Varnish
- 2. 部署 Varnish
- 3. 配置 Varnish
- 4. Varnish 的故障排除和管理
- 5. 课本练习
-
- 1. 浏览serverc上的web服务器提供的三个测试页面。
- 2. 在serverb上部署Varnish。
- 3. 配置Varnish。
- 4. 启用并启动varnish服务,然后打开防火墙端口。
- 5. 在serverc上监控Apache HTTP Server日志。
- 6. 在工作站的第一个终端上,通过Varnish查询static.html网页。
- 7. 通过Varnish查询set-cookie.php web页面,以确认Varnish没有缓存包含cookie的响应。
- 8. 通过Varnish查询set-cache.php网页。
- 9. 更新Varnish配置以缓存对象七天。
- 10. 因为您现在将对象长时间保存在缓存中,所以启用HTTP PURGE请求方法。
- 完成实验
- 总结
1. 描述 Varnish
-
大流量的 Web 服务器通常需要分担部分工作负载,以维持其命中率,降低响应时间
-
Varnish 是在 web 服务器之前的 web 加速器。客户端直接访问 Varnish
-
Varnish 代表客户端从后端 web 服务器检索并返回请求的对象
-
Varnish 也会缓存这些对象,以便为相同对象提供请求,降低 web 服务器负载
下图演示了Varnish如何在客户端第一次请求该对象时从后端web服务器检索该对象。该操作缓存失败,因为对象最初并不在缓存中。
-
Web 客户端请求对象。对于客户端,Varnish 的行为方式同web 服务器
-
Varnish 确定对象是否已在其缓存中
-
在本例中,对象不在缓存中。Varnish 从后端 web 服务器请求对象
-
Web 服务器将对象发到 Varnish
-
Varnish 将对象存储在其缓存中
-
Varnish 给客户端的回复中包含对象
下图显示了当一个对象在缓存中时,Varnish不需要联系后端web服务器就可以为该对象服务。这种行为称为缓存命中。
-
Web 客户端从 Varnish 请求对象
-
Varnish 确定对象是否已在缓存中且未过期
-
对象位于缓存中,Varnish 将其发回到客户端,而无需联系后端 web 服务器
**注意:**web客户端不再直接访问web服务器,而是查询Varnish。通常,您需要配置您的DNS服务器,以便url的主机部分指向Varnish服务器。
解释缓存行为
为了获得最佳性能,Varnish将对象缓存到内存中。因此,重新启动Varnish服务会清除缓存。
注:Varnish提供了一个持久性存储插件,将对象存储在磁盘上,但是Varnish开发人员已经不建议使用该插件。
Varnish 默认会缓存⼀切内容: HTML、CSS 和 JavaScript 文件;镜像和动态内容(如 PHP 程序)。但也有一些例外情况:
-
Varnish从不缓存设置HTTP cookie的响应。cookie通常存储特定于客户端的信息,比如会话id, Varnish不能为多个客户端提供这些响应。
-
Varnish不缓存HTTP PUT或POST请求。
-
Varnish在响应中识别Cache-Control HTTP报头。运行在后端web服务器上的web应用程序可以设置这个头来指示Varnish缓存应答多长时间(使用max-age值),或者不缓存它(使用no-cache或no-store值)。下面的示例使用curl命令和–head(或-I)选项来显示来自web应用程序的应答头:
[user@host ~]$ curl -I http://www.example.com/auth.php
HTTP/1.1 200 OK
Date: Fri, 17 Apr 2020 13:04:02 GMT
Server: Apache/2.4.37 (Red Hat Enterprise Linux)
X-Powered-By: PHP/7.2.11
Cache-Control: no-store
Set-Cookie: SESSIONID=8e8c5b64-f79b-4e15-b1ff-02c2c79b927b; expires=Sun, 17-
May-2020 13:03:23 GMT; Max-
Age=2592000; path=/
Content-Type: text/html; charset=UTF-8
可以使用Varnish configuration language (VCL)调优和调整Varnish的默认行为以满足需求。通过在VCL中开发,可以完全控制Varnish cachino机制。
解释TTL和清除机制
Varnish将对象保存在其缓存中一个特定的持续时间,称为生存时间(TTL)。当Varnish接收到对缓存中的对象的请求时,它首先确定对象的TTL值。如果对象已经过期,Varnish将丢弃它的副本,并从后端web服务器获取一个新版本。这种机制可以防止Varnish无限期地从其缓存中提供陈旧的内容。
缓存中的每个对象都有一个TTL值。当一个来自后端web服务器的回复包含一个特定TTL的Cache-control报头时,Varnish会为对象使用这个TTL。否则,Varnish将对象TTL设置为默认值2分钟。
可以通过Varnish配置更改默认TTL值。主要提供静态内容的Web服务器,如不经常更改的静态HTML页面和图像,可以受益于较高的TTL。
一些web应用程序和内容管理系统(CMS),如WordPress或MediaWiki,可以直接指示Varnish从其缓存中清除对象。例如,当用户修改Wiki页面时,MediaWiki向Varnish发送该页面的清除请求。对于这些应用程序,将TTL设置为一个非常高的值,例如一周,然后让应用程序控制Varnish缓存。
向Web应用程序提供客户端IP地址
一些web应用程序使用传入请求的源IP地址来识别它们的客户端。然而,如果Varnish位于web服务器前面,应用程序将看到来自Varnish服务器的请求,而不是来自单个客户端。
为了解决这个问题,Varnish自动将X-Forwarded-For HTTP头添加到它转发到后端web服务器的所有请求中。该头包含来自原始请求的客户端系统的IP地址:
...output omitted...
X-Forwarded-For: 172.25.250.9
...output omitted...
大多数web应用程序首先使用该头来识别客户端系统。
2. 部署 Varnish
安装 varnish 软件包
[root@host ~]# yum install varnish
启用并启动varnish systemd服务。
[root@host ~]# systemctl enable --now varnish
3. 配置 Varnish
Varnish将其配置划分为两个位置:
-
varnishd守护进程命令行参数
-
/etc/varnish/default.vcl实现方式文件
设置 Varnish 守护进程命令行参数
varnishd(1)手册页列出了您定义为varnishd守护进程的命令行选项的所有配置参数。这些参数控制进程的一般行为,如监听的网络端口、守护进程的Linux用户帐户或存储后端参数。
因为varnish systemd服务启动了varnishd守护进程,所以需要修改该服务来更改或添加命令行选项。
使用systemctl cat varnish命令显示当前服务详细信息。
[root@host ~]# systemctl cat varnish
# /usr/lib/systemd/system/varnish.service
[Unit]
Description=Varnish Cache, a high-performance HTTP accelerator
After=network-online.target
[Service]
...output omitted...
ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m
...output omitted...
在前面的输出中,systemd定义了使用Execstart参数运行的命令。
a [IP]: PORT选项指定Varnish监听传入客户端请求的TCP端口。选项的IP部分是要使用的网络接口的IP地址。如果没有设置,varnishd将监听所有服务器接口。可以为Varnish重复-a选项,以便在多个端口上侦听。
-s选项指定对象缓存的存储后端。malloc参数指示Varnish将对象缓存到内存中。上面输出的size(256)表示Varnish可以用于缓存的最大内存大小。当内存满的时候。Varnish可以清除旧对象。在一个专用于Varnish服务器的系统上,可能希望将缓存大小设置为系统物理内存的很大一部分。
配置网络端口
默认情况下,Varnish监听端口6081。因为web客户端通过Varnish访问你的web应用程序,通常配置Varnish监听端口80,默认的HTTP端口。
为此,修改varnish systemd服务如下:
- 为varnish服务创建systemd drop-in目录。Drop-in目录用于添加或覆盖个别设置,而不修改/ usr/lib/systemd/中的原始单元配置。永远不要修改/usr/lib/systemd/中的文件,因为包升级将覆盖您的自定义配置。相反,在/etc/systemd/ system/中创建一个子目录,使用原来的单元名,并添加.d。该目录下的插入配置文件必须以.conf结尾。
[root@host ~]# mkdir /etc/systemd/system/varnish.service.d/
- 要覆盖 [Service] 部分中的Execstart参数,请为该服务创建systemd配置文件。文件的名称必须以.conf扩展名结尾。设置varnishd -a选项为 :80
[root@host ~]# cat /etc/systemd/system/varnish.service.d/httpport.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m
第一个没有值的Execstart参数清除默认配置定义的命令。否则,systemd会依次执行所有Execstart命令。
- 强制systemd重新加载其配置。
[root@host ~]# systemctl daemon-reload
- 重新启动varnish服务。
[root@host ~]# systemctl restart varnish
- 打开防火墙端口。
[root@host ~]# firewall-cmd --permanent --add-service=http
[root@host ~]# firewall-cmd --reload
SELinux允许Varnish绑定到varnishd_port_t、http_cache_port_t和http_port_t端口类型。可以使用semanage port -l命令列出相关联的端口号。
[root@host ~]# semanage port -l | grep -w -e varnishd_port_t -e http_cache_port_t -e http_port_t | grep tcp
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
varnishd_port_t tcp 6081-6082
为了让Varnish监听任何其他端口,将varnishd_connect _any SELinux Boolean设置为on。
[root@host ~]# setsebool -P varnishd_connect_any on
使用VCL配置缓存行为
/etc/varnish/default.vcl配置文件控制对象缓存行为。在Varnish configuration language (VCL)中编写该配置文件。当Varnish启动时,它将该文件转换为二进制格式,然后加载并执行产生的代码。
介绍内置子程序
Varnish通过一系列内置子例程处理传入请求和后端响应。在/etc/varnish/default.vcl文件,可以重新定义这些子例程来修改默认行为。
例如,vcl_recv子例程处理来自web客户端的请求。在该子例程中,您通过req对象访问传入的请求细节。以/etc/varnish/default.vcl文件,指示Varnish跳过文件扩展名为.mp3或.oqg的文件的缓存
sub vcl_recv {
if (req.url ~ "\.(mp3|ogg)$") {
return (pass);
}
}
-
req对象的url属性包含请求url,例如/index.html或/sound.mp3操作符根据正则表达式测试url属性。
-
如果测试成功(即,URL 以 .mp3 或 .ogg 结尾),则子例程返回 pass 关键字。关键字指示 Varnish 跳过缓存,将请求直接传递到后端 web 服务器
注:vcl(7) man page 列出了所有可用的 req 对象属性和所有可用的运算符
vcl_backend_response 子例程处理来自后端 web 服务的回复。Varnish 通过 beresp 对象提供回复详细信息。当后端web 服务尝试将对象 TTL 强制设为超过⼀天时,下例可将该时间缩减为两小时
sub vcl_backend_response {
if (beresp.ttl > 1d) {
set beresp.ttl = 2h;
}
}
-
beresp 对象的 ttl 属性包含对象 TTL。测试可确定该 TTL 是否超过⼀天。在进入该 vcl_backend_response 子例程时,Varnish 将 beresp.ttl 属性设置为两分钟的默认值。但如果后端 web 服务器的回复包括 Cache-Control HTTP 标头,则Varnish 将从该标头设置 ttl 属性
-
子例程将 TTL 减少到仅为两个小时
Varnish定义并使用其他内置子例程。更多细节请参考Varnish文档。
声明访问控制列表并配置清除请求
/etc/varnish/default.vcl文件还可以包含访问控制列表(ACL)声明。这些声明定义了可以在子例程中使用的主机或IP地址列表。下面的示例定义了purge_allowed ACL,然后在vcl_recv子例程中使用该ACL。
acl purge_allowed {
# acl 声明定义了三个主机列表
"localhost";
"172.25.250.12";
"192.168.0.12";
}
sub vcl_recv {
if (req.method == "PURGE") {
# req 对象的 method 属性包含请求 HTTP 方法,如 GET、PUT或 POST。该测试将验证传入的请求是否使用 PURGE HTTP 方法。
if (!client.ip ~ purge_allowed) {
# client 对象提供客户端详细信息,如其 IP 地址。该测试将检查请求是否来自 purge_allowed ACL 中列出的客户端。该测试使用了求反运算符 !,因此如果客户端的 IP 地址不在列表中,则 Varnish 会将 405 HTTP 错误代码返回给客户端
return(synth(405, "This address is not allowed to send PURGE requests."));
}
return (purge);
# 子例程返回 purge 关键字。关键字指示 Varnish 从其缓存中清除对象。Varnish 在 req.url 中从请求 URL 识别对象,并在req.http.host 中识别请求的主机部分
}
}
前面的例子展示了如何配置Varnish来接受来自web应用程序的请求,从而从缓存中清除对象。您在ACL中提供的IP地址就是那些web应用程序的地址。
验证VCL语法
在重新启动varnish systemd服务之前,使用varnishd -C -f /etc/varnish/default.vcl命令测试您的配置。该命令编译VCL文件并显示生成的C代码。最重要的是,当检测到错误时,该命令返回一个非零值。
[root@host ~]# varnishd -C -f /etc/varnish/default.vcl
...output omitted...
[root@host ~]# echo $?
0
访问 Varnish 文档
varnish-docs 软件包在 /usr/share/doc/varnish-docs/html/目录下提供了 Varnish 文档
4. Varnish 的故障排除和管理
为了获得最佳性能,varnishd 守护进程不会写日志文件。取而代之,它将日志消息写入共享内存中的缓冲区中
可选的 varnishncsa 服务将监控该缓冲区,并将日志消息写入到 /var/log/varnish/varnishncsa.log 日志文件
日志文件与来自 Apache 的 access_log 文件类似:
[root@host ~]# cat /var/log/varnish/varnishncsa.log
172.25.250.9 - - [27/Apr/2020:07:06:31 -0400] "GET http://www.example.com/index.html HTTP/1.1" 200 32 "-" "curl/7.61.1"
172.25.250.9 - - [27/Apr/2020:07:12:26 -0400] "GET http://www.example.com/favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0)
Gecko/20100101 Firefox/68.0"
172.25.250.9 - - [27/Apr/2020:07:12:27 -0400] "GET http://www.example.com/HTTP/1.1" 200 32 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Firefox/68.0"
启用并启动varnishncsa可选服务systemd,方法如下:
[root@host ~]# systemctl enable --now varnishncsa
通过命令行管理Varnish
使用varnishadm命令行工具,您可以监视和重新配置Varnish,而不需要重新启动守护进程。使用该工具执行的修改不会在服务重新启动时持久,而是允许您临时修改活动配置
varnishadm命令接受子命令作为其第一个参数。如果不提供该子命令,varnishadm将启动交互式会话。下面的示例以非交互式和交互式的方式展示了status子命令的使用。status子命令显示varnishd守护进程的状态。
[root@host ~]# varnishadm status
Child in state running
[root@host ~]# varnishadm
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,4.18.0-147.el8.x86_64,x86_64,-junix,-smalloc,-sdefault,-hcritbit
varnish-6.0.2 revision 0458b54db26cfbea79af45ca5c4767c7c2925a91
Type 'help' for command list.
Type 'quit' to close CLI session.
varnish> status
200
Child in state running
varnish> quit
500
Closing CLI connection
[root@host ~]#
运行varnishadm帮助命令获取子命令列表。可以通过varnishadm帮助子命令或varnish-cli(7)手册页获得关于特定子命令的详细信息
下面的列表描述了其中的一些子命令。
varnishadm ban '*expression*'
ban子命令从缓存中清除对象。当后端web服务器有新内容时,该子命令非常有用,并且您希望Varnish在不等待TTL的情况下提供新内容。下面的命令清除URL部分为/的所有对象 /index.html。
[root@host ~]# varnishadm 'ban req.url == /index.html’
还可以使用正则表达式和~操作符来清除多个对象。下面的例子清除了所有的PNG图像。
[root@host ~]# varnishadm ban 'req.url ~ .*\.png’
需要在正则表达式中使用另一个 \ 字符来转义 \ 字符
varnishadm param.show *parameter*
param.show子命令显示Varnish参数的值。可以从varnishd(1)手册页获得所有这些参数的列表。下面的命令显示缺省TTL值。
[root@host ~]# varnishadm param.show default_ttl
default_ttl
Value is: 120.000 [seconds] (default)
Minimum is: 0.000
The TTL assigned to objects if neither the backend nor the VCL
code assigns one.
NB: This parameter is evaluated only when objects are created.
To change it for all objects, restart or ban everything.
varnishadm param.set *parameter value*
param.set子命令更改Varnish参数的值。这种更改不会在服务重新启动时持久存在。如果您想让这个更改持久,请更新varnish systemd服务配置,向varnishd守护进程添加-p选项。下面的命令将缺省TTL设置为12小时(43200秒)。
[root@host ~]# varnishadm param.set default_ttl 43200
varnishadm vcl.show boot
带有 boot 参数的 vcl.show 子命令将显示活动的 VCL
参考资料:varnishd(1)、varnishadm(1)、varnish-cli(7) 和 vcl(7) man page;varnish-docs 软件包中的 /usr/share/doc/varnish/ 和 /usr/share/doc/varnish-docs/html/
5. 课本练习
[student@workstation ~]$ lab optimizeweb-varnish start
lab命令在serverc上安装Apache HTTP Server,并部署一些web内容。
在本练习中,将Varnish Cache部署在serverb上,作为web服务器serverc运行的前端。
1. 浏览serverc上的web服务器提供的三个测试页面。
将在后面的步骤中使用这些测试页来验证Varnish安装。
[student@workstation ~]$ curl http://serverc.lab.example.com/static.html
This is serverc
[student@workstation ~]$ curl -I http://serverc.lab.example.com/set-cookie.php
HTTP/1.1 200 OK
Date: Wed, 30 Jun 2021 03:38:55 GMT
Server: Apache/2.4.37 (Red Hat Enterprise Linux)
X-Powered-By: PHP/7.2.11
Set-Cookie: SESSIONID=123456789; expires=Fri, 30-Jul-2021 03:38:55 GMT; Max-Age=2592000; path=/
Content-Type: text/html; charset=UTF-8
[student@workstation ~]$ curl -I http://serverc.lab.example.com/set-cache.php
HTTP/1.1 200 OK
Date: Wed, 30 Jun 2021 03:39:19 GMT
Server: Apache/2.4.37 (Red Hat Enterprise Linux)
X-Powered-By: PHP/7.2.11
Cache-Control: max-age=180
Content-Type: text/html; charset=UTF-8
2. 在serverb上部署Varnish。
[root@serverb ~]# yum -y install varnish
3. 配置Varnish。
配置varnish systemd服务,让varnishd守护进程监听80端口。
[root@serverb ~]# vim /etc/varnish/default.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "serverc.lab.example.com";
.port = "80";
}
[root@serverb ~]# varnishd -C -f /etc/varnish/default.vcl
...output omitted...
[root@serverb ~]# echo $?
0
[root@serverb ~]# systemctl cat varnish
[Unit]
Description=Varnish Cache, a high-performance HTTP accelerator
After=network-online.target
[Service]
Type=forking
KillMode=process
# Maximum number of open files (for ulimit -n)
LimitNOFILE=131072
# Locked shared memory - should suffice to lock the shared memory log
# (varnishd -l argument)
# Default log size is 80MB vsl + 1M vsm + header -> 82MB
# unit is bytes
LimitMEMLOCK=85983232
# Enable this to avoid "fork failed" on reload.
TasksMax=infinity
# Maximum size of the corefile.
LimitCORE=infinity
ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m
ExecReload=/usr/sbin/varnishreload
[Install]
WantedBy=multi-user.target
# 要覆盖默认服务配置,首先要为varnish服务创建一个drop-in目录。
[root@serverb ~]# mkdir /etc/systemd/system/varnish.service.d
# 覆盖启动服务的命令,将-a参数设置为:80。
[root@serverb ~]# vim /etc/systemd/system/varnish.service.d/port.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m
[root@serverb ~]# systemctl daemon-reload
4. 启用并启动varnish服务,然后打开防火墙端口。
[root@serverb ~]# systemctl enable --now varnish
Created symlink /etc/systemd/system/multi-user.target.wants/varnish.service → /usr/lib/systemd/system/varnish.service.
[root@serverb ~]# systemctl status varnish
● varnish.service - Varnish Cache, a high-performance HTTP accelerator
Loaded: loaded (/usr/lib/systemd/system/varnish.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/varnish.service.d
└─port.conf
Active: active (running) since Wed 2021-06-30 13:45:16 CST; 6s ago
Process: 2028 ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m (code=exited, status=0>
Main PID: 2029 (varnishd)
Tasks: 217
Memory: 91.8M
CGroup: /system.slice/varnish.service
├─2029 /usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m
└─2039 /usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m
[root@serverb ~]# firewall-cmd --permanent --add-service=http
success
[root@serverb ~]# firewall-cmd --reload
success
5. 在serverc上监控Apache HTTP Server日志。
通过这种方式,您可以看到来自Varnish安装的请求。
[root@serverc ~]# tail -f /var/log/httpd/access_log | nl
6. 在工作站的第一个终端上,通过Varnish查询static.html网页。
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
# 注意serverc上/var/log/httpd/access_log文件中的新日志消息。Varnish已经将请求转发到它的后端web服务器,在该消息中,请注意请求来自172.25.250.11。这是服务器的地址,Varnish在那里运行
[root@serverc ~]# tail -f /var/log/httpd/access_log | nl
1 172.25.250.9 - - [30/Jun/2021:11:38:48 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
2 172.25.250.9 - - [30/Jun/2021:11:38:55 +0800] "HEAD /set-cookie.php HTTP/1.1" 200 - "-" "curl/7.61.1"
3 172.25.250.9 - - [30/Jun/2021:11:39:19 +0800] "HEAD /set-cache.php HTTP/1.1" 200 - "-" "curl/7.61.1"
4 172.25.250.11 - - [30/Jun/2021:13:51:08 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
# 在工作站上,多查询几次static.html网页。
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
# 注意serverc上的/var/log/httpd/access_log文件没有更改,也没有报告这些新请求。这表明请求没有到达后端web服务器。Varnish从它的缓存返回文档。
# 从服务器上有会话的终端中,检索default_ttl参数的值。此参数指定Varnish应该多长时间从其缓存为文档提供服务。
[root@serverb ~]# varnishadm param.show default_ttl
default_ttl
Value is: 120.000 [seconds] (default)
Minimum is: 0.000
...output omitted...
# 等待120秒让文档过期,然后再次查询static.html页面。
[student@workstation ~]# sleep 120
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
# 注意serverc上/var/log/httpd/access_log文件中的新条目。
# Varnish再次从后端web服务器请求文档,因为它的副本已经过期。
4 172.25.250.11 - - [30/Jun/2021:13:51:08 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
5 172.25.250.11 - - [30/Jun/2021:13:57:29 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
7. 通过Varnish查询set-cookie.php web页面,以确认Varnish没有缓存包含cookie的响应。
[student@workstation ~]$ curl http://serverb.lab.example.com/set-cookie.php
...output omitted...
[student@workstation ~]$ curl http://serverb.lab.example.com/set-cookie.php
...output omitted...
[student@workstation ~]$ curl http://serverb.lab.example.com/set-cookie.php
...output omitted...
# 在serverc上,请注意/var/log/httpd/access_log文件中的新条目。
6 172.25.250.11 - - [30/Jun/2021:13:58:04 +0800] "GET /set-cookie.php HTTP/1.1" 200 111 "-" "curl/7.61.1"
7 172.25.250.11 - - [30/Jun/2021:13:58:06 +0800] "GET /set-cookie.php HTTP/1.1" 200 111 "-" "curl/7.61.1"
8 172.25.250.11 - - [30/Jun/2021:13:58:07 +0800] "GET /set-cookie.php HTTP/1.1" 200 111 "-" "curl/7.61.1"
# Varnish为每个请求查询后端web服务器,因为它没有缓存设置cookie的响应。
8. 通过Varnish查询set-cache.php网页。
这个请求的应答包括一个Cache-Control报头,它指示Varnish将文档缓存180秒,而不是默认的120秒。
[student@workstation ~]$ curl http://serverb.lab.example.com/set-cache.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Set Cache Expiration</title>
</head>
<body>
Cached for three minutes.
</body>
</html>
[student@workstation ~]$ sleep 120; curl http://serverb.lab.example.com/set-cache.php
# 在serverc上,注意在/var/log/httpd/access_log文件中,只有第一个请求到达后端web服务器。第二个请求没有新条目。
9 172.25.250.11 - - [30/Jun/2021:14:04:05 +0800] "GET /set-cache.php HTTP/1.1" 200 149 "-" "curl/7.61.1"
# Varnish不会向后端web服务器发送第二个请求,因为它将文档缓存180秒。
# 再等待60秒,然后发送一个新的请求。
[student@workstation ~]$ sleep 60; curl http://serverb.lab.example.com/set-cache.php
# 在serverc上,请注意/var/log/httpd/access_log文件中,这次Varnish将请求转发到后端web服务器,因为它的对象副本现在已经过期。
9 172.25.250.11 - - [30/Jun/2021:14:04:05 +0800] "GET /set-cache.php HTTP/1.1" 200 149 "-" "curl/7.61.1"
10 172.25.250.11 - - [30/Jun/2021:14:07:29 +0800] "GET /set-cache.php HTTP/1.1" 200 149 "-" "curl/7.61.1"
9. 更新Varnish配置以缓存对象七天。
在serverb 上,编辑 /etc/varnish/default.vcl配置文件,找到vcl_backend_response例程,然后设置beresp.ttl参数取值为七天
[root@serverb ~]# vim /etc/varnish/default.vcl
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
if (beresp.ttl == 120s) {
set beresp.ttl = 7d;
}
}
# 只有当对象的默认TTL为120秒时,该代码才强制将对象的TTL设置为7天。这个测试防止覆盖使用Cache-control头显式设置的应答的TTL。
[root@serverb ~]# varnishd -C -f /etc/varnish/default.vcl
...output omitted...
[root@serverb ~]# echo $?
0
[root@serverb ~]# systemctl restart varnish
# 验证:查询static.html网页,然后等待120秒。重新查询页面。
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
[student@workstation ~]$ sleep 120; curl http://serverb.lab.example.com/static.html
This is serverc
# 对于第一个请求,请注意serverc上/var/log/httpd/access_log文件中的新日志消息。
11 172.25.250.11 - - [30/Jun/2021:14:17:36 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
# 第二个请求没有新条目。这是因为对象TTL现在是7天,因此Varnish从它的缓存返回文档。
10. 因为您现在将对象长时间保存在缓存中,所以启用HTTP PURGE请求方法。
通过这种配置,web应用程序可以在需要刷新文档时发送清除请求。
在serverb 上,编辑 /etc/varnish/default.vcl配置文件,并找到vcl_recv例程。在例程之前添加一个acl _purge部分,然后编辑vcl_recv例程。
acl purge {
"localhost";
"172.25.250.12"; # serverc
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Not allowed."));
}
return (purge);
}
}
# 通过这种配置,Varnish只接受来自localhost和serverc的清除请求。
[root@serverb ~]# varnishd -C -f /etc/varnish/default.vcl
...output omitted...
[root@serverb ~]# echo $?
0
[root@serverb ~]# systemctl restart varnish
# 要验证工作,首先需要将一个对象加载到Varnish中,以便在接下来的步骤中清除它。为此,可以使用curl命令查询serverb.lab.example.com/static.html对象
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
# 注意serverc上/var/log/httpd/access_log文件中的新日志消息。
14 172.25.250.11 - - [30/Jun/2021:15:01:13 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
# Varnish从后端web服务器查询文档并将其存储在缓存中。
# 确认不能从workstation发送清除请求。在workstation上,尝试发送清除请求从缓存中删除对象。使用host标头指定对象的宿主部分。
[student@workstation ~]$ curl --header "Host: serverb.lab.example.com" -X PURGE http://serverb.lab.example.com/static.html
<!DOCTYPE html>
<html>
<head>
<title>405 Not allowed.</title>
</head>
<body>
<h1>Error 405 Not allowed.</h1>
<p>Not allowed.</p>
<h3>Guru Meditation:</h3>
<p>XID: 32770</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
# 该请求失败,因为Varnish配置不允许从workstation清除请求。
# 从serverb,通过localhost运行相同的清除请求。
[root@serverb ~]# curl --header "Host: serverb.lab.example.com" -X PURGE http://localhost/static.html
<!DOCTYPE html>
<html>
<head>
<title>200 Purged</title>
</head>
<body>
<h1>Error 200 Purged</h1>
<p>Purged</p>
<h3>Guru Meditation:</h3>
<p>XID: 5</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
# 请记住,处理HTTP PURGE请求的是Varnish。这些请求不是针对后端web服务器的,永远不会到达它。因此,serverc上的/ var/log/httpd/access_log文件永远不会报告这样的请求。
# 要确认该对象不再在缓存中,请从workstation执行一个新的查询。
[student@workstation ~]$ curl http://serverb.lab.example.com/static.html
This is serverc
# 注意serverc上/var/log/httpd/access_log文件中的新日志消息。
15 172.25.250.11 - - [30/Jun/2021:15:14:58 +0800] "GET /static.html HTTP/1.1" 200 16 "-" "curl/7.61.1"
# Varnish从后端web服务器查询文档,因为它从缓存中不再可用。
完成实验
[student@workstation ~]$ lab optimizeweb-varnish finish
总结
- 介绍Varnish。
- 介绍如何部署和设置Varnish以及常用排错情况。
- 演示Varnish如何运作并了解使用方法。
- 若喜欢金鱼哥的文章,顺手点个赞。也可点个关注,因为后续会不断上干货。