玩转 Varnish 缓存代理

Varnish 是互联网架构中重要的缓存代理组件。Varnish 一般跑在流量入口处,作为最前端一道防御,非常重要。

虽然 Varnish 并不像 Nginx 那么流行。Varnish 就像 Nginx 一样稳定高效,如果使用得当,能极大提升整体服务性能、并且降低资源消耗。

常见互联网架构中的多级缓存

  1. 将内容推送到用户身边的 CDN 缓存
  2. 类似 Varnish 的缓存代理
  3. 应用层缓存 Redis,Memcache
  4. 数据库缓存

为什么缓存代理很重要

  1. 一些事实:内容的变动比不变少得多;用户内容最终一致的容忍性。基于这 2 个事实,可以节约大量重复计算和资源。
  2. 延迟一般情况下对用户体验、商业业务的影响很大。所有互联网公司都在努力降低延迟,提升用户体验。
  3. CDN 有些情况下会大量回源,比如清空 CDN 缓存的时候,应用架构本身需要能抗 100% 流量的能力。

Varnish 的几个功能

1. HTTP Header 的修改

请求头的修改

unset req.http.cookie;
set req.http.X-EOOD = "EOOD";

返回头的修改

unset beresp.http.Set-Cookie;
set beresp.http.Cache-Control = "public, max-age=31536000";

2. 内容在 Varnish 状态的暴露

缓存的命中与否

if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}

3. 负载均衡

Varnish 也支持后端服务器的轮询之类的简单负载均衡,但是慎用。

4. 后端保护和容错

这个功能可能有些人没有注意到,但是确实非常有用的功能,在后端挂掉的时候,只读页面仍然会成功返回给客户。

set req.grace = 48h;

5. 访问控制

可以根据规则路由或者屏蔽某些访问,比如:

req.http.User-Agent
req.http.X-Forwarded-For
req.http.referer
...

简单密码保护:Basic Auth

if (! req.http.Authorization ~ "Basic XXXXXXX") {
error 401 "Restricted";
}

6. 多个后端合并

定义多个后端

backend ads {
.host = "ads.eood.cn";
.connect_timeout = 1s;
.first_byte_timeout = 30s;
.between_bytes_timeout = 5s;
}

backend blog {
.host = "blog.eood.cn";
.connect_timeout = 1s;
.first_byte_timeout = 30s;
.between_bytes_timeout = 5s;
}

根据域名、URL或者其他规则路由到不同的后端,这些规则可以是用户 IP, 甚至是用户 Cookie。

sub vcl_recv {

if (req.http.host ~ "ads" || req.url ~ "^/ads/") {
set req.backend = ads;
...
} else if(eq.http.host ~ "blog") {
set req.backend = blog;
}
}

7. 根据规则进行缓存

set beresp.ttl = 120s;

Varnish 运维常用命令

请求 URL 热点排名, 根据热点优化缓存策略

varnishtop -i rxurl

实时请求日志

varnishlog

可以通过 grep 进行过滤查看你需要的信息

varnishlog -c | grep 'google'

Varnish 的注意事项

防止连接粘滞,假如你有多个不同的后端,不添加这个会导致混乱,估计很多人踩过这个坑:

sub vcl_pipe {
set bereq.http.connection = "close";
}

URL 规划

一般缓存代理或者 CDN 都是可以通过配置 URL 规则实现不同 URL 模式使用不同的缓存策略,所以 URL 规划非常重要。
将动态请求和静态请求进行区分;将不同缓存级别的 URL 进行区分。这也有利于根据 URL 进行缓存清理。

最后

Varnish 是网站应用或者移动应用必不可少的缓存模块。如果你还没开始使用,就立刻把他加入到现有架构中吧。

注册 2.5 美元每月独立 IP 国内访问 30M 带宽 VPS

注册 DigitalOcean 256MB 内存, 20GB 硬盘 VPS, 获取 10 美元折扣

经验陷阱:完全相反的结论

亚马逊关于网页延迟对商业性能的影响有个非常流行的结论。

这个案例是这样的:1 秒的延迟每年会造成亚马逊 16 亿美元的损失。另一个说法是: 100ms 的延迟降低 1% 的销售额。

先后相反的结论

对于网页和应用延迟对转化率的影响,在我经历的案例中先后得到了完全相反的结论。

第一个案例是国外针对 Small Business 的一种 SaaS 服务。系统运行后其实网页的延迟很高,都在秒级别。后优化后速度提升很高,但是并没有看到对转化率和付费的正向影响。当时就想,那个结论完全不靠谱啊。

第二个案例是国内一家电商非常长的首页,但是巨型长页面却比打开速度更快的短页面拥有更高的转化率和购买率,其打开速度也在秒级别。貌似和之前的结论也是相反的。

第三个案例是国外一家媒体,网页延迟对用户存留和跳出率影响非常非常明显,比如刷新 CDN 缓存就能实时的明显看到各项指标的降低。这完全和亚马逊的结论类似。

经常在一些技术博客或者招聘广告上看到这样的文字:我们对技术追求很高,追求到毫秒级的优化。我的观点是假如性能提升无法对商业性能做出明显影响,做类似的优化投入是一种资源浪费。

结论

我们根据已有经验做出快速判断和快速决策,但是大部分已有结论的应用,都应该考虑规模、环境和例外情况,相信实际测试和数据。

假如没有经历这么多实际大型商业项目,恐怕做判断都会直接套用亚马逊的结论。
很容易对当前项目的方向(应用性能是否已经足够好,是否需要把资源投入到性能优化上)做出错误判断。

相关的链接

http://blog.gigaspaces.com/amazon-found-every-100ms-of-latency-cost-them-1-in-sales/
http://highscalability.com/latency-everywhere-and-it-costs-you-sales-how-crush-it
http://perspectives.mvdirona.com/2009/10/the-cost-of-latency/
http://www.websiteoptimization.com/speed/tweak/psychology-web-performance/
http://radar.oreilly.com/2008/08/radar-theme-web-ops.html

希望这些对你有用。如果觉得有用请收藏 RSS 或者扫码关注公众号 。

注册 Host1Plus 2.5 美元每月独立 IP 国内访问 30M 带宽 VPS

注册 DigitalOcean 256MB 内存, 20GB 硬盘 VPS