代码之家  ›  专栏  ›  技术社区  ›  Coomer

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

  •  12
  • Coomer  · 技术社区  · 16 年前

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

    我想要这些图像的请求(例如 http://www.mysite.com/p/1_1.jpg

    在Apache中,我是这样做的:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^p/([0-9]+_[0-9]+\.jpg)$ http://my_bucket.s3.amazonaws.com/$1 [P,L]
    

    location /p/ {
        if (-e $request_filename) {
            break;
        }
        proxy_pass http://my_bucket.s3.amazonaws.com/;
    }
    

    发生的情况是,每个请求都试图命中Amazon S3,即使该文件存在于磁盘上(如果它不存在于Amazon上,我会收到错误)。如果我删除代理传递行,则对磁盘上文件的请求确实有效。

    5 回复  |  直到 13 年前
        1
  •  35
  •   Dan Gayle    14 年前

    这不应该是一个使用 try_files

    location /p/ {
        try_files $uri @s3;
    }
    
    location @s3{ 
        proxy_pass http://my_bucket.s3.amazonaws.com;
    }
    

    确保S3URL上没有以下斜杠

        2
  •  15
  •   Anatoly    9 年前

    您可以像这样改进s3代理配置。改编自 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;
    }
    
        3
  •  4
  •   Anatoly    12 年前

    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;
    
        4
  •  0
  •   Chris Farmiloe    16 年前

    break nginx做的并不是你所期望的,它会做你最后要求它做的事情,如果你开始钻研制作模块,这是有意义的。。。但基本上是用 不存在 版本

    if (-f $request_filename) {
        break;
    }
    if(!-f $request_filename)
        proxy_pass  http://s3;
    }
    
        5
  •  0
  •   Coomer    16 年前

    location /p/ {
      if (!-f $request_filename) {
        rewrite ^/p/(.*)$ /ps3/$1 last;
        break;
      }
    }
    
    location /ps3/ {
      proxy_pass http://my_bucket.s3.amazonaws.com/;
    }