Proxy 本地磁盘或S3上文件的Nginx代理
因此,我正在将我的站点从Apache迁移到Nginx上,而我在这个场景中遇到了问题: 用户上传一张照片。这张照片被调整大小,然后复制到S3。如果磁盘上有合适的空间(或者文件无法传输到S3),则保留本地版本 我希望这些图像(例如)的请求首先在p/目录中查找。如果不存在本地文件,我希望将请求代理到S3并呈现图像(但不重定向) 在Apache中,我是这样做的: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)
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;