Proxy 本地磁盘或S3上文件的Nginx代理

Proxy 本地磁盘或S3上文件的Nginx代理,proxy,amazon-s3,nginx,Proxy,Amazon S3,Nginx,因此,我正在将我的站点从Apache迁移到Nginx上,而我在这个场景中遇到了问题: 用户上传一张照片。这张照片被调整大小,然后复制到S3。如果磁盘上有合适的空间(或者文件无法传输到S3),则保留本地版本 我希望这些图像(例如)的请求首先在p/目录中查找。如果不存在本地文件,我希望将请求代理到S3并呈现图像(但不重定向) 在Apache中,我是这样做的: RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^p/([0-9]+_[0-9]+\.jpg)

因此,我正在将我的站点从Apache迁移到Nginx上,而我在这个场景中遇到了问题:

用户上传一张照片。这张照片被调整大小,然后复制到S3。如果磁盘上有合适的空间(或者文件无法传输到S3),则保留本地版本

我希望这些图像(例如)的请求首先在p/目录中查找。如果不存在本地文件,我希望将请求代理到S3并呈现图像(但不重定向)

在Apache中,我是这样做的:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^p/([0-9]+_[0-9]+\.jpg)$ http://my_bucket.s3.amazonaws.com/$1 [P,L]
我尝试在Nginx中复制此行为如下:

location /p/ {
    if (-e $request_filename) {
        break;
    }
    proxy_pass http://my_bucket.s3.amazonaws.com/;
}
发生的情况是,每个请求都试图命中Amazon S3,即使该文件存在于磁盘上(如果它不存在于Amazon上,我会收到错误)。如果我删除代理传递行,则对磁盘上文件的请求确实有效


关于如何解决这个问题,你有什么想法吗?

break
并没有达到你所期望的效果,nginx做的最后一件事是你要求它做的,如果你开始钻研模块,这是有意义的。。。但基本上是用不存在的版本来保护您的代理权限


最后,我通过检查文件是否不存在来解决这个问题,如果存在,则重写该请求。然后,我处理重新编写的请求并将代理传递到那里,如下所示:

location /p/ {
  if (!-f $request_filename) {
    rewrite ^/p/(.*)$ /ps3/$1 last;
    break;
  }
}

location /ps3/ {
  proxy_pass http://my_bucket.s3.amazonaws.com/;
}

这不是使用
try\u文件的一个例子吗

location /p/ {
    try_files $uri @s3;
}

location @s3{ 
    proxy_pass http://my_bucket.s3.amazonaws.com;
}

确保S3URL上没有以下斜杠

您可以像这样改进S3代理配置。改编自:


感谢保留我的coderwall帖子:)出于缓存目的,您可以对其进行一些改进:

http {

  proxy_cache_path          /tmp/cache levels=1:2 keys_zone=S3_CACHE:10m inactive=24h max_size=500m;
  proxy_temp_path           /tmp/cache/temp;

  server {
    location ~* ^/cache/(.*) {
      proxy_buffering        on;
      proxy_hide_header      Set-Cookie;
      proxy_ignore_headers   Set-Cookie;
      ...
      proxy_cache            S3_CACHE;
      proxy_cache_valid      24h;
      proxy_pass             http://$s3_bucket/$url_full;
    }
  }

}
另一个建议是将解析器缓存扩展到5分钟:

resolver                  8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout          10s;

我最初尝试过,但是如果我有完整的
http://my_bucket.s3.amazonaws.com/
代理过程中调用。我得到以下错误:
重新启动nginx:2010/01/11 20:53:36[emerg]1485#0:“proxy_pass”可能在正则表达式给定的位置中没有URI部分,或者在命名位置中,或者在“if”语句中,或者在/etc/nginx/sites enabled/my_site.com:39中的“limit_except”块中,如果我删除尾部斜杠,Nginx将启动,但我的请求不再正确路由。有什么想法吗?nginx中的
if
具有非常不可预测的行为。尽管这很好,但建议尽可能使用
try_文件
,就像丹·盖尔的回答一样。如果
,请检查
的微妙之处。您可以共享virual.conf文件吗?回答得很好!清晰简单的解决方案。谢谢在proxy_pass指令中不需要尾部斜杠,这非常重要。它应该是这样的:
proxy\u pass http://$s3\u bucket$url\u full
http {

  proxy_cache_path          /tmp/cache levels=1:2 keys_zone=S3_CACHE:10m inactive=24h max_size=500m;
  proxy_temp_path           /tmp/cache/temp;

  server {
    location ~* ^/cache/(.*) {
      proxy_buffering        on;
      proxy_hide_header      Set-Cookie;
      proxy_ignore_headers   Set-Cookie;
      ...
      proxy_cache            S3_CACHE;
      proxy_cache_valid      24h;
      proxy_pass             http://$s3_bucket/$url_full;
    }
  }

}
resolver                  8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout          10s;