我安装了Apache2,nginx和Varnish。 Varnish接收请求,确定它的后端(静态转到nginx,动态转到Apache),从后端获取响应并在需要时缓存它。
Apache生成缩略图的其他事项。它使用一些特定的逻辑创建缩略图,对于处理器来说它非常昂贵。因此,Apache将拇指保存到磁盘,以便下次收到此缩略图的请求时,Varnish可以将其直接重定向到nginx。
这是一个问题: Varnish无法检查文件是否存在于文件系统的某处,这就是为什么它不知道是否可以使用nginx后端或者Apache应该首先生成缩略图的原因。
我目前采用的解决方法非常简单但很难看:
虽然这个算法在现实中似乎很简单但事实并非如此。 VCL配置文件中需要以下实现:
vcl_recv
中始终假设缩略图存在且所有请求必须重定向到nginx 如果未从某个特殊主机请求; vcl_fetch
捕获对象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代码检查文件是否存在?
答案 0 :(得分:4)
好的,如果有人对解决方案感兴趣,我在VCL配置中找到了一个带内联C的新版本。首先,我们必须添加一个函数来检查文件是否存在(在任何函数之外的文件顶部添加某个地方):
C{
#include <stdio.h>
#include <stdlib.h>
int exists (char *fname)
{
FILE *file;
if (file = fopen(fname, "r"))
{
fclose(file);
return 1;
}
return 0;
}
}C
我知道有更好的方法来检查文件是否存在,但VCL中没有主要标头:/
然后在vcl_recv
子例程中添加以下代码:
C{
if( exists("/local/file/path") == 1 ) {
VRT_l_req_backend(sp, VCL_conf.director[1]);
} else {
VRT_l_req_backend(sp, VCL_conf.director[2]);
}
}C
像魅力一样。
答案 1 :(得分:2)
你正在使用Varnish来制作它不适合的东西。它确实不可能检查文件是否存在,因为它不是首先提供文件。 Varnish只是暂时缓存文件或内存存储中的后端响应。
在这个设置中你真的需要清漆吗?让nginx检查文件是否存在或者将其转发给您的处理器会不会更有意义?
答案 2 :(得分:1)
为什么不使用Nginx的try_files指令在404上静默代理Apache的请求?至少对我来说似乎更合乎逻辑。
答案 3 :(得分:1)
您可能会对libvmod-utils感兴趣。您可以访问WASD42建议的内容,但可以直接使用VMOD(更清洁,应该有最新的改进和建议)而不是inline-C。
Inline-C很好,因为你可以做任何你需要的事情,但有时候VMOD更干净,并且不会破坏你的VCL语言。
下面是一个实现您需求的VCL示例:
import utils;
sub vcl_recv {
if(req.url ~ "^/thumb/") {
if (utils.exists("/srv/www/static/" + req.url)) {
set req.backend = nginx;
else {
set bereq.url = regsub(req.url, "/thumb/(filename)", "thumb_gen.php?filename=\1");
set req.backend = apache;
}
}
}