programing

Nginx 프록시 Amazon S3 리소스

nicescript 2021. 1. 13. 23:35
반응형

Nginx 프록시 Amazon S3 리소스


일부 WPO 작업을 수행하고 있으므로 PageSpeed는 브라우저 캐싱을 활용하도록 제안했습니다. 내 Nginx 서버의 일부 정적 파일에 대해 성공적으로 개선했지만 Amazon S3 서버에 저장된 이미지 파일이 여전히 누락되었습니다.

일부 헤더 메타 태그 (Expires 및 Cache-Control)를 포함하도록 S3의 각 파일을 업데이트하는 방법을 읽었습니다. 나는 이것이 좋은 접근법이 아니라고 생각합니다. 나는 수천 개의 파일을 가지고 있기 때문에 이것이 가능하지 않습니다.

가장 편리한 방법은 S3 파일을 프록시하도록 Nginx 1.6.0 서버를 구성하는 것입니다. 나는 이것에 대해 읽었지만 서버 구성에 전혀 능숙하지 않으므로 다음 사이트에서 몇 가지 예제를 얻었습니다. https://gist.github.com/benjaminbarbe/1961db5ffbaad57eff12

내 nginx 구성 파일의 서버 블록 안에이 위치 코드를 추가했습니다.

#inside server block
location /mybucket.s3.amazonaws.com/ {


        proxy_http_version     1.1;
        proxy_set_header       Host mybucket.s3.amazonaws.com;
        proxy_set_header       Authorization '';
        proxy_hide_header      x-amz-id-2;
        proxy_hide_header      x-amz-request-id;
        proxy_hide_header      Set-Cookie;
        proxy_ignore_headers   "Set-Cookie";
        proxy_buffering        off;
        proxy_intercept_errors on;      
        proxy_pass             http://mybucket.s3.amazonaws.com;
      }

확실히 이것은 나를 위해 작동하지 않습니다. 내 요청에 헤더가 포함되어 있지 않습니다. 따라서 먼저 요청이 위치와 일치하지 않는다고 생각합니다.

Accept-Ranges:bytes
Content-Length:90810
Content-Type:image/jpeg
Date:Fri, 23 Jun 2017 04:53:56 GMT
ETag:"4fd0be549fbcaf9b47c18a15146cdf16"
Last-Modified:Tue, 09 Jun 2015 09:47:13 GMT
Server:AmazonS3
x-amz-id-2:cKsq1qRra74DqVsTewh3P3sgzVUoPR8aAT2NFCuwA+JjCdDZfk7/7x/C0WPjBa51GEb4C8LyAIc=
x-amz-request-id:94EADB4EDD3DE1C1

Nginx를 통한 프록시 S3 파일에 대한 접근 방식은 매우 합리적입니다. 여러 문제를 해결하고 마스킹 URL, 프록시 캐시, 오프로드 SSL / TLS로 전송 속도 향상과 같은 추가 이점을 제공합니다. 당신은 거의 옳은 일을합니다. 완벽하게 만들기 위해 남은 것이 무엇인지 보여 드리겠습니다.

샘플 쿼리의 경우 원래 질문 에 대한 공개 의견언급 된 S3 버킷과 이미지 URL 을 사용합니다.

Amazon S3 파일의 헤더 검사부터 시작합니다.

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg

HTTP/1.1 200 OK
Date: Sun, 25 Jun 2017 17:49:10 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Content-Length: 378843
Server: AmazonS3

Cache-Control이 누락 된 것을 볼 수 있지만 조건부 GET 헤더가 이미 구성되었습니다. E-Tag / Last-Modified (브라우저의 클라이언트 측 캐시가 작동하는 방식)를 재사용 할 때 빈 Content-Length와 함께 HTTP 304를 얻습니다. 그 해석은 클라이언트 (우리의 경우 컬)가 서버에서 파일이 수정되지 않는 한 데이터 전송이 필요하지 않다고 리소스를 쿼리합니다.

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-None-Match: 37a907fc5dd7cfd0c428af78f09e95a9"

HTTP/1.1 304 Not Modified
Date: Sun, 25 Jun 2017 17:53:33 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Server: AmazonS3

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-Modified-Since: Wed, 21 Jun 2017 07:42:31 GMT"

HTTP/1.1 304 Not Modified
Date: Sun, 25 Jun 2017 18:17:34 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Server: AmazonS3

"PageSpeed가 브라우저 캐싱을 활용하도록 제안했습니다."이는 Cache = control이 누락되었음을 의미합니다. S3 파일 용 프록시 인 Nginx는 헤더 누락 문제를 해결할뿐만 아니라 Nginx 프록시 캐시를 사용하여 트래픽을 절약합니다.

macOS를 사용하지만 Nginx 구성은 수정없이 Linux에서 똑같은 방식으로 작동합니다. 단계별 :

1. Nginx 설치

brew update && brew install nginx

2. Nginx를 프록시 S3 버킷에 설정 (아래 구성 참조)

3. Nginx를 통해 파일을 요청합니다. 상기 살펴 보시기 바랍니다 서버 , 우리가 지금보다는 아마존 S3보다 Nginx에 참조 헤더 :

curl -I http://localhost:8080/s3/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg

HTTP/1.1 200 OK
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:30:26 GMT
Content-Type: binary/octet-stream
Content-Length: 378843
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Accept-Ranges: bytes
Cache-Control: max-age=31536000

Nginx를 통해 파일 요청

4. 조건부 GET과 함께 Nginx 프록시를 사용하여 파일을 요청합니다.

curl -I http://localhost:8080/s3/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-None-Match: 37a907fc5dd7cfd0c428af78f09e95a9"

HTTP/1.1 304 Not Modified
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:32:16 GMT
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Cache-Control: max-age=31536000

조건부 GET과 함께 Nginx 프록시를 사용하여 파일 요청

5. Nginx 프록시 캐시를 사용하여 파일을 요청하십시오. X-Cache-Status 헤더를 살펴보십시오. 값은 첫 번째 요청 후 캐시가 워밍업 될 때까지 MISS입니다.

curl -I http://localhost:8080/s3_cached/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg
HTTP/1.1 200 OK
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:40:45 GMT
Content-Type: binary/octet-stream
Content-Length: 378843
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Cache-Control: max-age=31536000
X-Cache-Status: HIT
Accept-Ranges: bytes

Nginx 프록시 캐시를 사용하여 파일 요청

Nginx 공식 문서를 기반으로 다음 옵션을 지원하는 최적화 된 캐싱 설정으로 Nginx S3 구성을 제공합니다.

  • proxy_cache_revalidate 는 원본 서버에서 콘텐츠를 새로 고칠 때 조건부 GET 요청을 사용하도록 NGINX에 지시합니다.
  • proxy_cache_use_stale 지시문에 대한 업데이트 매개 변수는 클라이언트가 항목을 요청할 때 NGINX가 항목에 대한 업데이트가 원본 서버에서 다운로드되는 동안 서버로 반복되는 요청을 전달하는 대신 오래된 콘텐츠를 전달하도록 지시합니다.
  • proxy_cache_lock이 가능 여러 클라이언트가 캐시 (A MISS)에 현재없는 파일을 요청하는 경우, 만 요청의 첫 번째는 원본 서버에 통해 허용

Nginx 구성 :

worker_processes  1;
daemon off;

error_log  /dev/stdout info;
pid        /usr/local/var/nginx/nginx.pid;


events {
  worker_connections  1024;
}


http {
  default_type       text/html;
  access_log         /dev/stdout;
  sendfile           on;
  keepalive_timeout  65;

  proxy_cache_path   /tmp/ levels=1:2 keys_zone=s3_cache:10m max_size=500m
                     inactive=60m use_temp_path=off;

  server {
    listen 8080;

    location /s3/ {
      proxy_http_version     1.1;
      proxy_set_header       Connection "";
      proxy_set_header       Authorization '';
      proxy_set_header       Host yanpy.dev.s3.amazonaws.com;
      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;
      add_header             Cache-Control max-age=31536000;
      proxy_pass             http://yanpy.dev.s3.amazonaws.com/;
    }

    location /s3_cached/ {
      proxy_cache            s3_cache;
      proxy_http_version     1.1;
      proxy_set_header       Connection "";
      proxy_set_header       Authorization '';
      proxy_set_header       Host yanpy.dev.s3.amazonaws.com;
      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_cache_revalidate on;
      proxy_intercept_errors on;
      proxy_cache_use_stale  error timeout updating http_500 http_502 http_503 http_504;
      proxy_cache_lock       on;
      proxy_cache_valid      200 304 60m;
      add_header             Cache-Control max-age=31536000;
      add_header             X-Cache-Status $upstream_cache_status;
      proxy_pass             http://yanpy.dev.s3.amazonaws.com/;
    }

  }
}

Nginx가 어떤 모듈로 컴파일되는지에 대한 세부 정보없이 모든 파일에 Expires 및 Cache-Control 헤더를 추가하는 두 가지 방법을 말할 수 있습니다.

Nginx S3 프록시

이것은 Nginx를 사용하여 S3 파일에 만료 캐시 제어 헤더를 추가하는 것입니다.

Nginx this set-misc-nginx-module needed to support Nginx S3 proxy & change/add expire, cache-control on the fly. This is a standard full guide from compilation to usage, this is great guide for nginx-extras for Ubuntu server. This is full guide with example with WordPress.

There are more S3 modules for extra things. Without those modules Nginx will not understand and config test (nginx -t) will pass test with wrong config. set-misc-nginx-module is minimum for your need. What you want has better example on this Github gist.

As not all are used with compilation and the setup is really slightly difficult, I am also writing the way to set Expires and Cache-Control header for all files in one Amazon S3 bucket.

Amazon S3 Bucket Expires and Cache-Control Header

Also, it is possible to set Expires and Cache-Control headers for all objects in one AWS S3 bucket with script or command line. There are several such free libraries and scripts on Github like this one, bucket explorer, Amazon's tool, Amazon's this doc and this doc. Command will be like this for that cp CLI tool :

aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
--expires 2027-09-01T00:00:00Z --acl public-read --cache-control max-age=2000000,public

From an architectural review, what you're trying to do is a wrong way to go about:

  • Amazon S3 is presumably optimised to be a highly available cache; by introducing a hand-rolled proxying layer on top of it, you're merely introducing an unnecessary extra delay and a huge point of failure, and also losing all the benefits that would come out of S3

  • Your performance analysis with regards to the number of files is incorrect. If you have thousands of files on S3, the correct solution would be to write a one-time script to change the requisite attributes on S3, instead of hand-rolling a proxying mechanism that you don't fully understand, and that would be executed many times over (ad nauseam). Doing the proxying would likely be a band-aid, and, in reality, will likely decrease the performance, not increase it (even if you'd get to have a stateless automated tool tell you otherwise). Not to mention that it would also be an unnecessary resource drain, and may contribute to actual performance issues and heisenbugs down the line.


That said, if you're still up for proxying with adding the headers, the correct way to do so with nginx would be by using the expires directive.

예를 들어, 적절한 위치에 지시문 expires max;전후에 배치 할 수 proxy_pass있습니다.

expires지시어는 자동으로 올바른 설정을 처리합니다 Cache-Control너무, 당신을 위해 헤더를; 그러나 add_header사용자 정의 응답 헤더를 수동으로 추가하려는 경우 지시문 을 사용할 수도 있습니다.

참조 URL : https://stackoverflow.com/questions/44639182/nginx-proxy-amazon-s3-resources

반응형