我在上面安装了 Apache2、nginx 和 Varnish。Varnish 接收请求,确定它用于什么后端(静态到 nginx,动态到 Apache),从后端获取响应并在需要时缓存它。
除其他外,Apache 会生成缩略图。它使用一些特定的逻辑创建缩略图,并且处理器非常昂贵。因此,Apache 将缩略图保存到磁盘,以便下次收到此缩略图的请求时,Varnish 可以将其直接重定向到 nginx。
这里有一个问题: Varnish 无法检查文件是否存在于文件系统中的某个位置,这就是为什么它不知道是否可以使用 nginx 后端或者 Apache 是否应该首先生成缩略图。
我目前采用的解决方法非常简单但很难看:
- Varnish 收到缩略图请求;
- Varnish 向 nginx 发送请求;
- 如果 nginx 找不到缩略图文件,它会回复 404 错误,并且 Varnish 会将请求重定向到 Apache。
虽然这个算法实际上看起来很简单,但事实并非如此。VCL 配置文件中需要以下实现:
vcl_recv
始终假设缩略图存在,如果不是从某个特殊主机请求,则所有请求都必须重定向到nginx;- 在
vcl_fetch
catch 对象 HTTP 状态中,如果它是 404 并且资源是缩略图,则将主机重写为特殊主机并重新启动进程:
VCL:
if( obj.status == 404 ) {
if(req.url ~ "^thumb/") {
set req.http.host = "thumb_generator.site.com";
set req.url = regsub(req.url, "/thumb/(filename)", "thumb_gen.php?filename=\1");
restart;
}
}
也许有一些更好的方法来解决这个问题?我知道 Varnish 在 VCL 中支持 C,也许使用 C 代码检查文件是否存在更好?