玩转 Varnish 缓存代理

jopen 9年前

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

来自:http://blog.eood.cn/varnish-cache