2012-11-13 30 views
2

我已经将光油(3.0.3)作为两个Web服务器前面的负载平衡器/静态缓存。我有一个使用Original Pull方法设置的CDN。如果我手动从我的网站上的图像中获取URL,请放入CDN地址,我可以验证原始拉动正在工作,并且图像被拉到CDN并送达。用光油重写图像到CDN URL的请求

我的应用程序是相当复杂的,我测试这个CDN,看它是否显著加快了Web应用程序,所以我不希望重写我的任何PHP代码使用CDN的图像,只是还没有。

我希望做的是设置了光油改写为图像文件收到的请求,并通过CDN,而不是直接从两个Apache服务器在我的群拉他们。

我已经通过清漆文档阅读和一对夫妇HOWTO的关于做类似的事情在网上,但我不能让它正常工作,在这里需要一些帮助。

这里有几个不同的方法,我试着这样做(编辑为简洁起见):

sub vcl_recv { 
    #if request is image, redirect to CDN 
    if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 
     set req.http.host = "cdn.domain.com/"; 
     error 750 req.http.host + req.url; 

    } 

} 
sub vcl_error { 
    if (obj.status == 750) { 
    set obj.status = 302; 
    set obj.http.Location = obj.response; 
    return(deliver); 
    } 
} 

这没有奏效。它导致了无处不在的图像,任何出现的都是使用.webp扩展名,所以它没有被上面的条件处理。

所以,我想这一点:

backend cdn { 
     .host = "cdn.domain.com"; 
     .port = "80"; 
} 
sub vcl_recv { 
    #if request is image, redirect to CDN 
    if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 

     set req.backend = cdn; 
     return(lookup); 
    } 

}

这显示在页面上的一些图像,但查看其来源时,他们看着被来自Apache服务器来(域名WASN” t的CDN),只有大约一半的图像显示......可能是浏览器缓存。

我想在这里输入一些内容,谢谢你们。

有没有办法使用清漆这种重定向?将Varnish设置为nginx以重写对cdn的请求会更好吗?

UPDATE: 使用下面给出两个答案,我有重定向工作,并在现有的ACL允许CDN拉图像直接VS重定向到自身。但是,虽然我验证了ACL允许通过使用自己的外部IP来连接,但CDN并未从服务器获取新图像。它给出了502错误(奇数<),而不是将图像从本地服务器拉到CDN并提供服务。这是我的vcl_recv块貌似现在:

acl cdn { 
    "ip.of.CDN"; 
} 

sub vcl_recv { 
    #if request is image, redirect to CDN 
    if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 
     if(!client.ip ~ cdn){ 
      error 750 "http://cdn.domain.com" + req.url; 
     } 
    } 

} 
sub vcl_error { 
    if (obj.status == 750) { 
    set obj.status = 302; 
    set obj.http.Location = obj.response; 
    return(deliver); 
    } 
} 

回答

3

你绝对可以用清漆做到这一点很容易 - 无需安装nginx的或任何东西。事实上,你的第一个解决方案非常接近于诀窍。它只需要一些修改。

sub vcl_recv { 
    #if request is image, redirect to CDN 
    if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 
     error 750 "http://cdn.domain.com" + req.url; 
    } 
} 
sub vcl_error { 
    if (obj.status == 750) { 
    set obj.status = 302; 
    set obj.http.Location = obj.response; 
    return(deliver); 
    } 
} 

你忘了的“http://”从你的CDN网址,并且可以从主机忽略最后一个斜线所有req.url s的/开始。

您还需要确保vcl_error代码是第一个在vcl_error()中运行的代码。即如果您有多个vcl_error的定义,请确保在达到if (obj.status == 750)检查之前,它们都不会提供任何输出。

请记住,此解决方案会导致所有客户端浏览器先查询您的服务器,然后在302重定向后向CDN发出另一个请求。这给每个图像加载带来了明显的延迟,并且可能不是确定CDN是否可以提高应用性能的最佳方式。

更新:关于您在尝试从您的来源提取内容时显示502错误的CDN问题。依靠远程IP地址来确定重定向是相当危险的,因为CDN可以很好地使用多个服务器来执行重定向,并且地址可以随时间变化。这将使VCL非常费力且容易出错。

是否可以设置唯一的虚拟主机供CDN使用?例如originpull.domain.com并设置CDN,以便从该地址取代内容而不是主要的www.domain.com地址?

然后,您可以修改vcl_recv()如下:

sub vcl_recv { 
    #if request is image and request is not made from CDN, redirect to CDN 
    if (req.http.host != "originpull.domain.com" && 
     req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 
     error 750 "http://cdn.domain.com" + req.url; 
    } 
} 

这将确保从CDN请求将不会被重定向。

+0

感谢这里的细节。关于302的问题和延迟虽然。因此,这种设置的典型流程是:浏览器点击Varnish>传递给两个服务器之一>读取html>从html的源URL中呈现html和图像。 使用光油302:浏览器点击Varnish>将浏览器传递到服务器以获取图像的html和CDN>渲染html和图像。 我的理解是否正确?如果是这样,这应该比在httpd.conf或.htaccess中写入重定向要好,因为它早期发生在浏览器中,而image/html应该来自两个并行源? (CDN /本地服务器) – Jmichelsen

+0

并按照我的问题与一个问题...使用mod_pagespeed和ModPagespeedMapRewriteDomain重写所服务的HTML ..这将比这种Varnish方法更少或更有效吗? MapRewriteDomain的问题在于它完成了一切,不仅仅是图像,我不想要这些,但是对于性能测试,这将会在哪里? – Jmichelsen

+0

除了@ arober11解决的问题之外,这似乎很好地工作。当我激活此vcl时,所有图像都显示为来自CDN。但是,不在CDN上的图像已经不在其中。我将推荐的acl放在适当的位置,通过在那里添加我自己的外部IP来验证它是否工作正常,但是由于某种原因,CDN并未拉取图像。 502错误 – Jmichelsen

1

假设您有CDN将其从网站中拉出来,并且您没有手动将图像推送到CDN。您是否错过了从重写或后端代理中简单排除CDN网络?由于CDN需要能够直接从您的站点提取图像的副本以填充缓存。

已经有一段时间我打光油,从不专家,但大意如下的东西可能工作:

# Defnine the IP ranges of the CDN server. 
acl cdn { 
     "localhost"; 
     "11.22.33.0"/24; 
} 

... 

    #if request is image, redirect to CDN, unless from the CDN 
    if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") { 
     if (!client.ip ~ cdn) { 
      error 750 "http://cdn.domain.com" + req.url; 
     } 
    } 
... 
+0

啊,尝试了上述解决方案,并开始得到来自CDN 502错误,因为这一切永远无法打我的服务器的原始图像。我正在尝试混合解决方案..感谢这一点 – Jmichelsen