2010-01-12 10 views
12

तो मैं अपाचे से और Nginx पर दूर अपनी साइट से आगे बढ़ रही हैं और मुझे इस परिदृश्य में परेशानी आ रही:Nginx प्रॉक्सी फ़ाइलें करने के लिए या S3

उपयोगकर्ता एक तस्वीर अपलोड करता है। इस तस्वीर का आकार बदल गया है, और उसके बाद एस 3 की प्रतिलिपि बनाई गई है। यदि डिस्क पर उपयुक्त कमरा है (या फ़ाइल को S3 में स्थानांतरित नहीं किया जा सकता है), तो स्थानीय संस्करण रखा जाता है।

मुझे पी/निर्देशिका में पहली बार देखने के लिए इन छवियों (जैसे http://www.mysite.com/p/1_1.jpg) के लिए अनुरोध चाहिए। यदि कोई स्थानीय फ़ाइल मौजूद नहीं है, तो मैं 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 हिट करने के लिए प्रयास करता है, भले ही फ़ाइल डिस्क पर मौजूद है (और यदि यह अमेज़ॅन पर मौजूद नहीं है, तो मुझे त्रुटियां मिलती हैं।) यदि मैं proxy_pass लाइन को हटा देता हूं, तो डिस्क पर फ़ाइलों के लिए अनुरोध करें।

इसे ठीक करने के तरीके पर कोई विचार?

+0

क्या आप virual.conf फ़ाइल साझा कर सकते हैं। – Thoman

उत्तर

33

इस try_files उपयोग का एक उदाहरण हो सकता है नहीं करना चाहिए?

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

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

यकीन है कि वहाँ S3 यूआरएल

+0

महान जवाब! स्पष्ट और सरल समाधान। धन्यवाद! –

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 [उभरना] 1485 # 0:" proxy_pass "में नियमित अभिव्यक्ति, या नामित स्थान के अंदर दिए गए स्थान में यूआरआई भाग नहीं हो सकता है, या "if" कथन के अंदर, या /etc/nginx/sites-enabled/my_site.com में "limit_except" ब्लॉक के अंदर: 39' यदि मैं पिछला स्लैश हटा देता हूं, तो Nginx शुरू हो जाएगा, लेकिन मेरे अनुरोधों को रूट नहीं किया जाता है सही ढंग से और भी। कोई विचार? – Coomer

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' का उपयोग करने की अनुशंसा की जाती है, जैसे दान गेल के जवाब में। 'If' की subtleties के लिए http://wiki.nginx.org/IfIsEvil देखें। –

12

पर एक निम्नलिखित स्लेश आप इस तरह अपने S3 प्रॉक्सी config सुधार सकता है नहीं है सुनिश्चित करें। https://stackoverflow.com/a/44749584 से अनुकूलित: मेरे coderwall पोस्ट :) रखने के लिए

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

धन्यवाद कैशिंग प्रयोजन के लिए आप इसे थोड़ा सुधार कर सकते हैं:

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;' –

संबंधित मुद्दे