RH358优化Web服务器流量--使用Varnish缓存静态网页

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: RH358优化Web服务器流量--使用Varnish缓存静态网页

RH358优化Web服务器流量–使用Varnish缓存静态网页

本章节介绍如何部署和使用缓存服务Varnish,相当于CDN的形式加快访问。

RH358专栏地址:https://blog.csdn.net/qq_41765918/category_11532281.html

1. 描述 Varnish

  • 大流量的 Web 服务器通常需要分担部分工作负载,以维持其命中率,降低响应时间

  • Varnish 是在 web 服务器之前的 web 加速器。客户端直接访问 Varnish

  • Varnish 代表客户端从后端 web 服务器检索并返回请求的对象

  • Varnish 也会缓存这些对象,以便为相同对象提供请求,降低 web 服务器负载

下图演示了Varnish如何在客户端第一次请求该对象时从后端web服务器检索该对象。该操作缓存失败,因为对象最初并不在缓存中。

  1. Web 客户端请求对象。对于客户端,Varnish 的行为方式同web 服务器

  2. Varnish 确定对象是否已在其缓存中

  3. 在本例中,对象不在缓存中。Varnish 从后端 web 服务器请求对象

  4. Web 服务器将对象发到 Varnish

  5. Varnish 将对象存储在其缓存中

  6. Varnish 给客户端的回复中包含对象

下图显示了当一个对象在缓存中时,Varnish不需要联系后端web服务器就可以为该对象服务。这种行为称为缓存命中。

  1. Web 客户端从 Varnish 请求对象

  2. Varnish 确定对象是否已在缓存中且未过期

  3. 对象位于缓存中,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;
    }
}
  1. beresp 对象的 ttl 属性包含对象 TTL。测试可确定该 TTL 是否超过⼀天。在进入该 vcl_backend_response 子例程时,Varnish 将 beresp.ttl 属性设置为两分钟的默认值。但如果后端 web 服务器的回复包括 Cache-Control HTTP 标头,则Varnish 将从该标头设置 ttl 属性

  2. 子例程将 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如何运作并了解使用方法。
  • 若喜欢金鱼哥的文章,顺手点个赞。也可点个关注,因为后续会不断上干货。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
22天前
|
缓存 监控 定位技术
|
1月前
|
Web App开发 前端开发 JavaScript
探索Python科学计算的边界:利用Selenium进行Web应用性能测试与优化
【10月更文挑战第6天】随着互联网技术的发展,Web应用程序已经成为人们日常生活和工作中不可或缺的一部分。这些应用不仅需要提供丰富的功能,还必须具备良好的性能表现以保证用户体验。性能测试是确保Web应用能够快速响应用户请求并处理大量并发访问的关键步骤之一。本文将探讨如何使用Python结合Selenium来进行Web应用的性能测试,并通过实际代码示例展示如何识别瓶颈及优化应用。
123 5
|
1月前
|
机器学习/深度学习 缓存 监控
利用机器学习优化Web性能和用户体验
【10月更文挑战第16天】本文探讨了如何利用机器学习技术优化Web性能和用户体验。通过分析用户行为和性能数据,机器学习可以实现动态资源优化、预测性缓存、性能瓶颈检测和自适应用户体验。文章还介绍了实施步骤和实战技巧,帮助开发者更有效地提升Web应用的速度和用户满意度。
|
1月前
|
SQL 关系型数据库 数据库
优化Web开发流程:Python ORM的优势与实现细节
【10月更文挑战第4天】在Web开发中,数据库操作至关重要,但直接编写SQL语句既繁琐又易错。对象关系映射(ORM)技术应运而生,让开发者以面向对象的方式操作数据库,显著提升了开发效率和代码可维护性。本文探讨Python ORM的优势及其实现细节,并通过Django ORM的示例展示其应用。ORM提供高级抽象层,简化数据库操作,提高代码可读性,并支持多种数据库后端,防止SQL注入。Django内置强大的ORM系统,通过定义模型、生成数据库表、插入和查询数据等步骤,展示了如何利用ORM简化复杂的数据库操作。
61 6
|
1月前
|
缓存 前端开发 JavaScript
探索现代Web开发中的前端性能优化策略
【10月更文挑战第5天】探索现代Web开发中的前端性能优化策略
|
1月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
56 3
|
1月前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
47 3
|
1月前
|
缓存 前端开发 JavaScript
构建高性能Web应用:优化前端性能的策略
构建高性能Web应用:优化前端性能的策略
|
2月前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
在快速发展的Web开发领域,高性能与高效响应是衡量应用质量的重要标准。随着Python在Web开发中的广泛应用,如何利用Python的协程(Coroutine)与异步函数(Async Functions)特性来优化Web应用的性能,成为了许多开发者关注的焦点。本文将从实战角度出发,通过具体案例展示如何运用这些技术来提升Web应用的响应速度和吞吐量。
30 1
|
2月前
|
缓存 负载均衡 前端开发
优化Web应用性能的十种策略
在当今的数字化时代,Web应用的性能直接影响用户体验和业务成效。本文深入探讨了优化Web应用性能的十种策略,从前端的资源优化到后端的架构改进,涵盖了缓存机制、异步加载、数据库优化等关键技术手段。这些策略不仅能提升响应速度,还能显著减少服务器负担和带宽消耗,为开发者提供了一系列切实可行的解决方案。
下一篇
无影云桌面