Varnish:三明治里的牛肉

您可能听说过与Varnish有关的术语“Web-Delivery-三明治”,这是一个非常贴切的元数据::

┌─────────┐
│ browser │
└─────────┘                                            ┌─────────┐
           \                                          ┌─────────┐│
┌─────┐     ╔═════════╗    ┌─────┐    ┌─────────┐    ┌─────────┐│┘
│ app │ --- ║ Network ║ -- │ TLS │ -- │ Varnish │ -- │ Backend │┘
└─────┘     ╚═════════╝    └─────┘    └─────────┘    └─────────┘
            /
┌────────────┐
│ API-client │
└────────────┘

三明治的顶层‘TLS’负责处理TLS(“HTTPS”)加密,这意味着它必须能够访问验证您的网站的加密证书。

三明治的最底层是您的Web服务器、CDN、API服务器、业务后端系统和您的Web内容的所有其他来源。

Varnish位于中间,它为您的网络流量提供缓存、策略、分析、可见性和缓解。

Varnish的工作原理

对于每个请求,Varnish都会通过‘VCL’程序来决定应该发生什么:哪个后端有这个内容,我们可以缓存它多长时间,这个请求是否可以访问它,它是否应该被重定向到其他地方,等等。如果特定的后端关闭,Varnish可以找到另一个或替换不同的内容,直到它恢复。

您的第一个VCL程序可能很简单,例如,只是在两个不同的后端服务器之间拆分流量:

sub vcl_recv {
   if (req.url ~ "^/wiki") {
       set req.backend_hint = wiki_server;
   } else {
       set req.backend_hint = wordpress_server;
   }
}

当您将VCL程序加载到Varnish中时,它被编译成C程序,该C程序被编译成共享库,然后Varnish加载并调用该库,因此VCL代码是 fast

Varnish做的每一件事都被记录在‘VSL’日志记录中,这些日志记录可以被实时检查和监控,或者以本地或NCSA格式被记录下来以供以后使用,当我们说‘一切’时,我们指的是 everything **

*   << Request  >> 318737
-   Begin          req 318736 rxreq
-   Timestamp      Start: 1612787907.221931 0.000000 0.000000
-   Timestamp      Req: 1612787907.221931 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.0.2.24 39698 a1
-   ReqMethod      GET
-   ReqURL         /vmods/
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: varnish-cache.org
-   ReqHeader      Accept: text/html, application/rss+xml, […]
-   ReqHeader      Accept-Encoding: gzip,deflate
-   ReqHeader      Connection: close
-   ReqHeader      User-Agent: Mozilla/5.0 […]
-   ReqHeader      X-Forwarded-For: 192.0.2.24
-   VCL_call       RECV
-   VCL_acl        NO_MATCH bad_guys
-   VCL_return     hash
[…]

这些 VSL 日志记录被写入共享内存中的循环缓冲区,其他程序可以通过支持的API从那里订阅它们。其中一个这样的计划是 varnishncsa 它会生成NCSA样式的日志记录:

192.0.2.24 - - [08/Feb/2021:12:42:35 +0000] "GET http://vmods/ HTTP/1.1" 200 0 […]

VARNISH也是为正常运行时间而设计的,不需要重新启动VARNISH来更改VCL程序,事实上,可以同时加载多个VCL程序,您可以立即在它们之间切换。

使用Varnish进行缓存

当Varnish收到请求时,VCL可以决定在缓存中寻找可重用的答案(如果有的话),这将减少一个将负载加载到后端应用程序数据库的请求。缓存命中只需不到1毫秒,通常只需几微秒。

如果缓存中没有任何可用的东西,则来自后端的应答可以再次在VCL控制下在缓存中放置一段时间,以便将来对同一对象的请求可以在那里找到它。

Varnish懂得 Cache-Control 如果您的后端服务器发送一个Http标头,但最终VCL程序会决定是否缓存以及缓存多长时间,以及是否要发送不同的 Cache-Control 头到客户端,VCL也可以做到这一点。

使用Varnish的内容合成

Varnish支撑件 ESI - Edge Side Includes 这使得向由来自不同后端的不同位组成的客户端发送响应成为可能,其中非常重要的脚注是不同位可以具有非常不同的高速缓存策略。

使用ESI,后端可以告诉Varnish将另一个对象的内容编辑到一个HTML页面中::

<H1>Todays Top News</H1>
<ESI:include src="/topnews"/>

这个 /topnews 请求将像Varnish中的每个其他请求一样被处理,VCL将决定它是否可以被缓存,哪个后端应该提供它,等等,所以即使示例中的整个对象不能被缓存,例如如果页面是登录用户的动态内容, /topnews 对象可以被缓存,并且可以在所有用户之间从缓存共享。

使用Varnish的内容策略

由于VCL完全控制每个请求,并且VCL可以即时更改,因此Varnish是实现反应性和说明性内容策略的一个很好的工具。

说明性内容-政策可以是从遵守联合国关于向不同客户提供本地语言内容使用IP号码访问列表的制裁,到根据“断开连接的权利”法律关闭对员工网络邮件的访问。

Varnish,特别是VCL,非常适合对请求进行分类和收集指标,以便进行实时A/B测试或在迁移到新的后端系统时使用。

被动内容策略可以是任何东西,从阻止访问受感染的后端或修复新产品上二维码的URL,到在后端重建数据库时延长缓存时间。

Varnish是通用的

Varnish是为在现代类Unix操作系统上运行而编写的,这些操作系统包括Linux、FreeBSD、OS/X、OpenBSD、NetBSD、Solaris、Omnios、SmartOS等。

Varnish可以在任何CPU架构上运行:i386、AMD64、arm32、arm64、MIPS、POWER、riscV、s390--随便你怎么说。

Varnish可以部署在专用硬件上,可以部署在虚拟机、监狱、容器、云中,也可以部署为服务或您可能关心的任何其他方式。

不幸的是, sudo make me a sandwich 功能还没有准备好,所以你必须自己做,但点击左侧导航菜单中的“下一主题”,我们将告诉你食谱……