用光油将图像请求重写到CDN URL

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

我的应用程序相当复杂,我正在测试此CDN以查看它是否显着加速了网络应用程序,所以我不想重写我的任何php代码以使用CDN图像。

我想要做的就是设置Varnish重写为图像文件收到的请求,并将它们通过CDN而不是直接从群集中的两个Apache服务器中提取出来。

我已经阅读了Varnish文档和一些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服务器(域名不是CDN的域名),只有大约一半的图像正在显示......可能是浏览器缓存。

我喜欢这里的一些输入,谢谢你们。

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

更新 :使用下面给出的两个答案,我有重定向工作和一个ACL的地方,让CDN拉直接图像重定向到自己。 但是,虽然我验证了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);
  }
}

你可以很容易地用Varnish做这个 - 不需要设置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);
  }
}

您从CDN URL中忘记了“http://”,并且可以省略主机的最后一个斜杠,因为所有req.url都以/开头。

您还需要确保vcl_error代码是在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的请求永远不会被重定向。


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

自从我和Varnish一起玩了一段时间后,我从来不是一个专家,但是可以沿着以下方向行事:

# 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;
        }
    }
...
链接地址: http://www.djcxy.com/p/41291.html

上一篇: Rewrite Requests for Images to CDN URL with Varnish

下一篇: Displaying image in browser using Django development server and Apache