2010-01-12 44 views
12

所以我感動我的網站遠離Apache和Nginx的上,和我有這個情況麻煩:Nginx的代理服務器上的文件本地磁盤或S3

用戶上傳的照片。這張照片被調整大小,然後複製到S3。如果磁盤上有合適的空間(或文件無法傳輸到S3),則保留本地版本。

我想請求這些圖像(如http://www.mysite.com/p/1_1.jpg)先查看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/; 
} 

什麼情況是,每個請求試圖打亞馬遜S3,即使該文件存在於磁盤上(如果它在Amazon上不存在,我也會收到錯誤。)如果我刪除了proxy_pass行,那麼請求磁盤上的文件DO工作。

有關如何解決此問題的任何想法?

+0

你能分享virual.conf文件嗎? – Thoman 2013-05-30 19:24:26

回答

33

不應該這個是使用try_files的例子嗎?

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

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

確保沒有你可以提高你的S3代理的配置是這樣的S3網址

+0

很好的回答!清晰簡單的解決方案。謝謝! – 2017-06-21 10:58:56

0

break不是你所期望的那樣nginx會做最後一件事你問它,這是有道理的,如果你開始挖掘周圍的模塊......但基本上保護你的proxy_pass與不存在版本

if (-f $request_filename) { 
    break; 
} 
if(!-f $request_filename) 
    proxy_pass http://s3; 
} 
+3

我最初嘗試過,但是如果我在'proxy_pass'調用中有完整的'http:// my_bucket.s3.amazonaws.com /',Nginx就不會啓動。我得到以下錯誤: '重新啓動nginx:2010/01/11 20:53:36 [emerg] 1485#0:「proxy_pass」在正則表達式給定的位置或命名的位置內可能沒有URI部分,或者在「if」語句中或在/etc/nginx/sites-enabled/my_site.com中的「limit_except」塊中:39' 如果我刪除了尾部斜槓,Nginx將啓動,但我的請求不會被路由正確的更多。有任何想法嗎? – Coomer 2010-01-12 05:06:16

0

我最終通過檢查,如果該文件不存在解決這個,如果是這樣,改寫該請求。然後我處理再書面請求並做proxy_pass那裏,就像這樣:

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

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

nginx中的'if'具有非常不可預知的行爲。儘管這很好,但建議儘可能使用'try_files',就像Dan Gayle的回答一樣。查看http://wiki.nginx.org/IfIsEvil瞭解if的細節。 – 2012-09-05 09:57:17

12

接下來的斜線。從https://stackoverflow.com/a/44749584改編:

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

location @s3 { 
    set $s3_bucket  'your_bucket.s3.amazonaws.com'; 
    set $url_full   '$1'; 

    proxy_http_version  1.1; 
    proxy_set_header  Host $s3_bucket; 
    proxy_set_header  Authorization ''; 
    proxy_hide_header  x-amz-id-2; 
    proxy_hide_header  x-amz-request-id; 
    proxy_hide_header  x-amz-meta-server-side-encryption; 
    proxy_hide_header  x-amz-server-side-encryption; 
    proxy_hide_header  Set-Cookie; 
    proxy_ignore_headers Set-Cookie; 
    proxy_intercept_errors on; 

    resolver    8.8.4.4 8.8.8.8 valid=300s; 
    resolver_timeout  10s; 
    proxy_pass    http://$s3_bucket$url_full; 
} 
2

感謝讓我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; 
+1

** proxy_pass **指令中不需要結尾斜槓,這非常重要。它應該看起來像這樣: 'proxy_pass http:// $ s3_bucket $ url_full;' – 2017-06-21 17:01:12

相關問題