캐싱하지 않는 역방향 프록시로서의 Nginx

캐싱하지 않는 역방향 프록시로서의 Nginx

Nginx를 캐싱 역방향 프록시로 구성하려고 합니다. 원본 서버는 Apache이며 중요한 경우 WordPress 인스턴스를 호스팅합니다.

역방향 프록시 기능은 예상대로 작동하지만 캐시가 작동하지 않는 것 같습니다. 동일한 정적 리소스를 연속으로 두 번 얻으면 x-proxy-cache: MISS두 번 얻습니다.

assodigitale.it는 도메인이고 원본 서버 IP 주소는 138.201.87.123이고 Nginx 프록시 IP 주소는 138.201.87.124입니다.

원본 서버는 프록시가 리소스를 캐시할 수 있도록 응답하는 것 같습니다.

$ curl --connect-to ::138.201.87.123:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
date: Sun, 11 Mar 2018 20:59:39 GMT
server: Apache/2.4.25 (Debian)
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
accept-ranges: bytes
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
content-type: image/jpeg

예상대로 프록시 서버에 대한 첫 번째 요청으로 인해 MISS가 발생합니다.

$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:04:00 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes

Nginx 프록시에 대한 두 번째 요청은 HIT로 이어져야 하지만 또 다른 MISS로 이어집니다.

$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:05:52 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes

내 nginx 구성의 관련 부분은 다음과 같습니다.

proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;

server {
    listen 443 ssl http2;
    ssl on;
    server_name assodigitale.it;

    ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    location / {
        proxy_cache revproxy;
        add_header X-Proxy-Cache $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=4838400; includeSubDomains; preload";

        proxy_pass  https://138.201.87.123;
        proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
        proxy_cache_bypass $http_x_forceflushcacheurl;
        proxy_cache_lock on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_hide_header Upgrade;
        proxy_buffering off;
        proxy_connect_timeout       600;
        proxy_send_timeout          600;
        proxy_read_timeout          600;
        send_timeout                600;
        proxy_ignore_headers Set-Cookie;

        http2_push_preload on;
        client_max_body_size 64M;
    }
}

디렉토리 /srv/cache/nginx에는 755개의 권한과 www-data소유자가 있으며 Nginx는 www-data. 실제로 Nginx는 거기에 폴더를 작성하지만 0 1 2 3 4 5 6 7 8 9 a b c d e f상당히 크고 일반 트래픽보다 훨씬 많은 사이트의 경우 전체 공간이 이제 344Kb를 차지합니다.

위와 동일한 curl명령을 시도하지만 이미지 대신 페이지를 사용하면 동일한 결과가 나오며 항상 MISS입니다.

Nginx가 리소스 캐시를 거부하는 이유는 무엇입니까?

답변1

Proxy_buffering을 설정해야 합니다 on. 그렇지 않으면 nginx가 응답을 캐시하지 않습니다!

공식문서말했다:

버퍼링이 비활성화되면 응답은 수신되는 즉시 동기적으로 클라이언트에 전달됩니다. nginx nginx will not try to read the whole response from the proxied server.가 서버로부터 동시에 수신할 수 있는 데이터의 최대 크기는 proxy_buffer_size 지시어에 의해 설정됩니다.

답변2

제가 실행하는 다른 유사한 Nginx 프록시의 구성을 복사하여 웹사이트에 적용했더니 이제 작동합니다.

현재 사용하고 있는 구성은 다음과 같습니다.

proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;    
server {
    listen 443 ssl http2;
    ssl on;
    server_name assodigitale.it;

    ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;

        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;    
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    60;
        ssl_session_timeout  10m;

    location / {
            proxy_cache revproxy;
            add_header X-Proxy-Cache $upstream_cache_status;

            proxy_pass  https://138.201.87.123;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
            proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
            proxy_cache_lock on;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_hide_header      Upgrade;
            proxy_buffering on;
            proxy_connect_timeout       600;
            proxy_send_timeout          600;
            proxy_read_timeout          600;
            send_timeout                600;
            client_max_body_size 64M;
    }
}

이것이 문제를 해결하기 때문에 답변이 될 수 있지만 이것이 왜 작동하는지(또는 더 정확하게는 이전 구성이 왜 작동하지 않는지) 이해하지 못하므로 내 답변을 받아들이지 않겠습니다.

어쩌면 누군가가 캐시를 작동하게 만드는 두 가지 구성에서 특정한 차이점을 발견할 수 있을 것입니다. 이는 수용 가능한 답변이 될 것입니다.

답변3

비슷한 문제가있었습니다. 우리는 nginx를 s3 버킷의 프록시 캐시로 사용하고 있었습니다(IP 화이트리스트를 지원할 수 있도록). 프록시가 https에서 서비스를 제공하고 있음에도 불구하고 https 끝점에서 소싱하지 않는 것으로 나타났습니다. nginx가 그것을 좋아하지 않는 것 같습니다. http에서 로 전환한 후에는 https문제가 없습니다.

관련 정보