본문 바로가기

HTTP 요청과 응답에 대한 캐싱 로직 정의 VCL (Varnish Configuration Language)

Varnish Configuration Language (VCL) 코드는 특정 HTTP 요청과 응답에 대해 캐싱 로직을 정의하여 캐싱 동작을 조정하는 것입니다. Varnish에서는 기본적으로 모든 페이지를 캐시할 수 있는 가능성이 있지만, 실제로 캐시되는지 여부는 여러 조건에 따라 달라집니다. 이러한 조건에는 HTTP 헤더, 요청 메소드, 설정된 VCL 로직 등이 포함됩니다. 따라서 모든 페이지가 자동으로 캐시되는 것은 아니며, 다음과 같은 요소들이 캐시 여부를 결정짓습니다.

  1. HTTP 메소드: 일반적으로 GET 요청과 HEAD 요청만 캐시됩니다. POST나 PUT 같은 다른 요청 메소드는 기본적으로 캐시되지 않습니다.
  2. HTTP 헤더: Cache-Control, Pragma, Expires 등의 헤더는 응답이 캐시될 수 있는지, 얼마나 오래 캐시될 수 있는지를 제어합니다. 예를 들어, Cache-Control: no-cache 헤더가 설정된 응답은 캐시되지 않습니다.
  3. VCL 설정: 사용자가 Varnish Configuration Language (VCL)을 사용하여 특정 요청을 캐시에서 제외하거나 특정 조건에서만 캐시하도록 세밀하게 제어할 수 있습니다. 예를 들어, 쿠키를 포함하는 요청을 캐시에서 제외하거나, 특정 사용자 에이전트에 대해 다른 캐시 정책을 적용할 수 있습니다.
  4. 콘텐츠 유형: 일부 유형의 콘텐츠(예: 동적으로 생성된 페이지)는 캐시하기 어렵거나 캐시하지 않을 수 있습니다. 반면 정적 콘텐츠(예: 이미지, CSS, JavaScript 파일)는 캐시하기 쉽고, 일반적으로 캐시됩니다.
  5. 캐시 용량과 만료 정책: 캐시 서버의 저장 공간이 제한되어 있으며, 캐시된 콘텐츠는 설정된 만료 시간에 따라 또는 공간이 필요할 때 제거될 수 있습니다.

요약하면, 모든 페이지가 자동으로 캐시되는 것은 아니며, Varnish의 설정과 특정 HTTP 요청 및 응답의 성격에 따라 캐시 여부가 결정됩니다. Varnish는 매우 유연하며, 사용자는 VCL을 통해 캐시 동작을 세밀하게 제어할 수 있습니다.

Varnish Configuration Language (VCL) - Finite State Machine

Varnish Configuration Language (VCL)에서 캐시 여부를 결정하는 설정은 여러 단계와 조건을 통해 정의됩니다. VCL은 요청과 응답의 처리 방식을 매우 세밀하게 제어할 수 있도록 설계되었으며, 캐시 동작을 결정하는 데에는 주로 다음과 같은 함수(서브루틴)들이 사용됩니다.

1. vcl_recv 서브루틴

  • 클라이언트로부터의 요청을 처음 받았을 때 실행됩니다.
  • 요청을 캐시할지, 직접 오리진 서버로 전달할지 결정할 수 있습니다.
  • 예를 들어, 특정 쿠키가 있는 요청이나 특정 사용자 에이전트의 요청을 캐시에서 제외할 수 있습니다.

2. vcl_backend_response 서브루틴

  • 오리진 서버로부터 응답을 받았을 때 실행됩니다.
  • 응답을 캐시할지 여부를 결정하고, 캐시 시간(TTL)을 설정할 수 있습니다.
  • 예를 들어, Set-Cookie 헤더가 있는 응답을 캐시하지 않도록 설정할 수 있습니다.

3. vcl_hash 서브루틴

  • 캐시 키를 생성할 때 사용됩니다.
  • URL, 쿠키, 헤더 등을 기반으로 캐시 항목의 고유성을 결정합니다.
  • 동일한 캐시된 콘텐츠를 요청하는 다른 요청들이 같은 캐시 항목을 사용하도록 합니다.

4. vcl_deliver 서브루틴

  • 클라이언트에게 응답을 보내기 직전에 실행됩니다.
  • 응답에 추가적인 헤더를 추가하거나 수정할 수 있습니다.

예시

다음은 VCL 설정의 간단한 예시로, 특정 조건에서 캐시를 하지 않도록 설정하는 방법을 보여줍니다.

sub vcl_recv {
    // 특정 쿠키가 있을 경우 캐시를 하지 않음
    if (req.http.Cookie ~ "sessionid") {
        return (pass); // 오리진 서버로 직접 전달
    }
}

sub vcl_backend_response {
    // 오리진 서버의 응답에 Set-Cookie가 있는 경우 캐시하지 않음
    if (beresp.http.Set-Cookie) {
        set beresp.uncacheable = true;
        set beresp.ttl = 120s; // 이 조건에서만 적용되는 TTL 설정
        return (deliver);
    }
}

이 설정은 특정 쿠키를 포함하는 요청이나 Set-Cookie 헤더를 포함하는 응답을 캐시하지 않도록 합니다. VCL은 매우 유연하여, 사이트의 요구 사항에 맞춰 다양한 캐시 정책을 구현할 수 있습니다.

 

VCL (Varnish Configuration Language)에서 vcl_backend_response 서브루틴을 사용하여 응답이 캐시되어야 하는 경우와 캐시되지 않아야 하는 경우를 다루는 방법은 매우 유연합니다. 다음은 vcl_backend_response에서 캐시할 조건과 캐시하지 않을 조건을 모두 포함하는 예시 코드입니다.

 

이 코드 예시에서는 몇 가지 기준을 설정하여 캐시 로직을 결정합니다.

  • Set-Cookie 헤더가 있는 응답은 캐시하지 않습니다.
  • 특정 경로(/no-cache)로의 요청에 대한 응답은 캐시하지 않습니다.
  • 그 외의 모든 GET 요청에 대한 응답은 2분 동안 캐시합니다.
sub vcl_backend_response {
    // 오리진 서버의 응답에 Set-Cookie가 있거나 특정 경로 요청인 경우 캐시하지 않음
    if (beresp.http.Set-Cookie || bereq.url ~ "^/no-cache") {
        // 캐시하지 않도록 설정
        set beresp.uncacheable = true;
        set beresp.ttl = 0s; // TTL을 0초로 설정하여 캐시하지 않음
        return (deliver); // 클라이언트에게 즉시 응답 전달
    } else if (bereq.method == "GET") {
        // GET 요청에 대한 응답이며, 위의 조건들을 만족하지 않는 경우
        // 캐시 가능하도록 설정
        set beresp.ttl = 120s; // TTL을 120초(2분)로 설정
        set beresp.grace = 1h; // 오래된 콘텐츠를 제공할 수 있는 유예 시간을 1시간으로 설정
        // 추가적으로, 캐시 키에 영향을 미치는 요소가 있다면 여기에서 처리할 수 있습니다.
    }
    // 그 외의 경우 (예: POST 요청에 대한 응답 등)에는 기본 Varnish 처리를 따름
}

이 코드는 다음과 같이 작동합니다.

  • Set-Cookie 헤더가 있는 응답이나 /no-cache 경로로의 요청에 대한 응답은 캐시하지 않습니다. 이는 캐시를 회피해야 하는 동적 콘텐츠나 특정 사용자에게 맞춤화된 콘텐츠를 처리하는 데 유용합니다.
  • GET 요청에 대한 나머지 응답은 2분 동안 캐시됩니다. 이는 대부분의 정적 콘텐츠나 변경되지 않는 콘텐츠에 적합한 설정입니다.
  • 유예 시간(grace period) 설정을 통해 오리진 서버가 다운되었거나 응답을 늦게 하는 경우에도 사용자에게 콘텐츠를 제공할 수 있습니다.

Varnish의 VCL은 매우 강력하고 유연하여, 웹사이트의 요구 사항에 맞게 캐시 정책을 세밀하게 조정할 수 있습니다.

 

Varnish의 TTL (Time To Live) 설정은 Varnish 캐시 서버 내에서의 캐시 동작을 제어합니다. 이 설정은 오리진 서버로부터 받은 응답이 Varnish 캐시에 얼마나 오래 저장될지를 결정합니다. TTL이 0으로 설정되면, Varnish는 해당 응답을 캐시에 저장하지 않습니다. 이는 오리진 서버로부터의 응답이 캐시되지 않음을 의미하며, 각 요청이 오리진 서버로 직접 전송될 것임을 나타냅니다.

 

여기에서의 캐시는 클라이언트 브라우저 캐시와는 완전히 별개입니다. 클라이언트 브라우저 캐시는 브라우저가 직접 관리하며, 웹 페이지나 자원들이 사용자의 컴퓨터에 저장되어, 재방문 시 빠르게 로드할 수 있도록 합니다. 브라우저 캐시 동작은 Cache-Control, Expires 같은 HTTP 헤더에 의해 제어됩니다. 이러한 헤더는 웹 서버나 오리진 서버에서 설정하며, 클라이언트 브라우저에게 어떤 응답을 얼마나 오래 저장할지 지시합니다.

 

따라서, Varnish에서 TTL을 설정하는 것은 Varnish 캐시의 동작에만 영향을 미치며, 클라이언트 브라우저 캐시와는 직접적인 연관이 없습니다. 그러나, Varnish 또는 다른 역방향 프록시 캐시를 사용하는 경우, 이러한 설정이 최종 사용자의 경험에 간접적으로 영향을 미칠 수 있습니다. 예를 들어, Varnish 캐시를 통해 빠르게 콘텐츠를 제공함으로써 웹 사이트의 로딩 속도를 개선할 수 있습니다.

 

beresp.uncacheable 변수는 Varnish Configuration Language (VCL) 내에서 오리진 서버로부터 받은 응답이 캐시 가능한지 여부를 제어하는 데 사용됩니다. 이 변수를 설정하면 특정 응답이 Varnish 캐시에 저장되지 않도록 할 수 있으며, 이는 주로 동적 콘텐츠나 개인화된 콘텐츠를 처리할 때 유용합니다.

beresp.uncacheable 주요 용도

  • 캐시 방지: 이 변수를 true로 설정하면 해당 응답이 캐시되지 않습니다. 캐시를 회피해야 하는 응답, 예를 들어 사용자별 맞춤 응답이나 변동성이 높은 데이터 등을 처리할 때 사용됩니다. 이는 특정 조건에서만 캐시를 방지하고 싶을 때 유용하게 사용할 수 있습니다.
  • 조건부 캐시 제어: beresp.uncacheable을 조건부로 설정함으로써, 특정 HTTP 헤더, 쿠키, 요청 경로 등의 조건에 따라 캐시 동작을 세밀하게 제어할 수 있습니다. 이를 통해 성능 최적화와 함께 콘텐츠의 신선도를 보장할 수 있습니다.
  • 캐시 로직의 유연성 제공: Varnish는 기본적으로 효율적인 캐싱을 목표로 하지만, 모든 응답이 캐싱에 적합한 것은 아닙니다. beresp.uncacheable을 통해 개발자는 캐시 정책을 그들의 필요에 맞게 조정할 수 있으며, 이를 통해 서버 부하를 줄이고 사용자 경험을 향상시킬 수 있습니다.

예제 사용법

sub vcl_backend_response {
    if (beresp.http.Set-Cookie) {
        // 응답에 Set-Cookie 헤더가 있는 경우, 캐시하지 않음
        set beresp.uncacheable = true;
        set beresp.ttl = 0s; // TTL을 0으로 설정하여 즉시 만료
    }
}

위 예제는 오리진 서버로부터의 응답에 Set-Cookie 헤더가 포함되어 있을 경우, 해당 응답을 캐시하지 않도록 설정하는 간단한 VCL 로직을 보여줍니다. 이렇게 함으로써, 사용자 개인별 정보를 포함하는 응답이 공유 캐시에 저장되어 다른 사용자에게 잘못 제공되는 것을 방지할 수 있습니다.

 

요약하자면, beresp.uncacheable은 Varnish에서 응답의 캐시 가능성을 제어하는 중요한 변수로, 캐시 정책을 세밀하게 조정하고 특정 요구 사항에 맞게 캐시 동작을 설정하는 데 사용됩니다.

 

beresp.ttl = 10s;beresp.uncacheable = true;를 동시에 설정하는 경우가 있는데, 첫눈에 모순처럼 보일 수 있습니다. beresp.ttl은 캐시된 객체가 얼마나 오랫동안 유효할지를 결정하는 시간을 설정하는 반면, beresp.uncacheable = true;는 객체가 캐시되지 않아야 함을 명시합니다.

 

그러나 Varnish에서 이러한 설정을 함께 사용하는 경우는 다음과 같은 특별한 상황에서 유용할 수 있습니다. 그 이유는 Varnish의 세밀한 캐싱 로직과 관련이 있습니다.

Grace Period와 Soft Purge

Varnish에서는 beresp.ttlberesp.uncacheable를 함께 설정하는 주된 이유 중 하나가 'grace period'와 'soft purge' 기능을 활용하기 위함입니다.

  • Grace Period: 캐시된 객체의 TTL이 만료된 후에도, 새로운 백엔드 요청이 성공할 때까지 캐시된 내용을 계속 제공할 수 있는 기간을 의미합니다. 이를 통해 백엔드가 일시적으로 응답하지 않거나 지연되는 경우에도 사용자에게 콘텐츠를 제공할 수 있습니다.
  • Soft Purge: 캐시에서 객체를 즉시 제거하지 않고, 대신 TTL을 만료시키는 방식입니다. 이렇게 하면 객체는 곧바로 캐시에서 사라지지 않고, grace period 동안 여전히 사용할 수 있습니다.

사용 사례

beresp.ttl = 10s;beresp.uncacheable = true;를 함께 사용하는 경우는 다음과 같은 특별한 상황에서 유용할 수 있습니다.

  • 높은 가용성 요구: 시스템이 항상 응답해야 하는 경우, 백엔드로부터 새로운 콘텐츠를 가져오는 동안에도 사용자에게 뭔가를 보여줄 필요가 있습니다. 이 설정을 통해 최신 데이터를 가져오는 동안이라도, 짧은 시간 동안이라도 캐시된 데이터를 제공할 수 있습니다.
  • 일시적 캐싱: 특정 조건 하에서만 일시적으로 캐싱을 허용하고자 할 때 사용할 수 있습니다. 예를 들어, 특정 시간 동안만 캐시를 활성화하려는 경우나, 캐시된 데이터를 즉시 사용하지 않으면서도 백엔드 부하를 줄이고자 할 때 유용합니다.

이러한 설정은 Varnish 캐시의 동작을 세밀하게 제어할 수 있게 하며, 특히 고가용성과 성능 최적화가 필요한 환경에서 중요한 역할을 합니다. 다만, 실제 사용 사례와 목적에 따라 적절한 설정을 결정하는 것이 중요합니다.

Grace Time과 관련된 설정

Varnish는 grace 시간이라는 개념을 사용하여, 콘텐츠의 TTL이 만료된 후에도 오래된 콘텐츠를 일정 시간 동안 제공할 수 있도록 합니다. 이는 오리진 서버가 다운되었거나 응답을 생성하는 데 시간이 걸리는 경우에 유용하게 사용됩니다.

  • beresp.uncacheable = true로 설정하면, 특정 응답을 캐시에 저장하지 않도록 할 수 있지만,
  • set beresp.ttl = 10s;와 같이 TTL을 설정하고, 추가로 grace 시간을 설정하면, 이 응답은 직접적으로 캐시되지는 않지만, grace 기간 동안은 캐시된 것처럼 사용될 수 있습니다.

이런 설정은 오리진 서버로부터의 새로운 응답을 받아오는 동안 사용자에게 서비스 중단 없이 콘텐츠를 계속 제공하고자 할 때 유용합니다.

잠재적인 설정 실수 또는 특별한 로직 구현

또 다른 가능성으로는, 이러한 설정이 특별한 케이스를 위한 맞춤형 로직 구현의 일부일 수 있습니다. 예를 들어, 개발자가 beresp.uncacheabletrue로 설정하기 전에 이미 TTL을 설정했을 수 있으며, 이후 로직 변경 과정에서 uncacheabletrue로 설정했을 수 있습니다. 이 경우, TTL 설정은 실제로는 적용되지 않습니다.

 

정리하자면, 일반적인 상황에서 beresp.uncacheable = trueset beresp.ttl = 10s;를 동시에 사용하는 것은 불필요하거나 혼란을 초래할 수 있습니다. 그러나 특별한 상황이나 grace 시간을 활용하는 고급 캐싱 전략의 일부로서 의도적으로 사용될 수 있습니다. 항상 현재의 요구 사항과 Varnish의 동작 방식을 충분히 이해한 상태에서 캐시 설정을 조정해야 합니다.

 

Varnish는 기본 설정에서 POST 요청을 캐시하지 않습니다. 이는 HTTP POST 요청이 일반적으로 데이터를 서버로 전송하거나 서버의 상태를 변경하는 데 사용되기 때문입니다. 예를 들어, 사용자가 웹 폼을 통해 정보를 제출하거나 로그인을 할 때 POST 요청이 사용됩니다. 이러한 요청의 결과는 사용자마다 다르거나 요청마다 달라질 수 있으므로, 캐싱하기에 적합하지 않습니다.

 

HTTP 캐싱은 주로 GET 요청에 대해서 이루어지며, 이는 정보를 검색하는 데 사용되고 서버의 상태를 변경하지 않습니다. GET 요청의 응답은 요청한 리소스에 대한 정보를 포함하며, 이러한 응답은 여러 사용자에게 동일하게 적용될 수 있기 때문에 캐싱하기에 적합합니다.

 

Varnish와 같은 캐시 시스템에서 POST 요청을 캐싱하는 것은 일반적으로 권장되지 않지만, 특정 상황에서 필요한 경우 Varnish 구성을 조정하여 POST 요청에 대한 캐싱을 활성화할 수 있습니다. 그러나 이는 매우 신중하게 고려되어야 하며, 캐싱할 데이터가 안전하고, 캐싱으로 인해 예기치 않은 부작용이 발생하지 않도록 해야 합니다. 대부분의 경우, Varnish의 기본 동작을 변경하기보다는 캐시할 수 있는 GET 요청을 최대한 활용하는 것이 좋습니다.

 

POST 요청을 캐시하지 않는다는 근거는 HTTP 명세와 캐싱에 대한 일반적인 원칙에서 찾을 수 있습니다. 이러한 근거를 제시할 때 다음과 같은 점을 참고할 수 있습니다.

  1. HTTP/1.1 명세 (RFC 7231): HTTP 프로토콜에 대한 RFC 문서는 HTTP 메서드의 정의와 사용 방법에 대한 명세를 제공합니다. RFC 7231은 HTTP/1.1의 일부로, POST 메서드가 서버에 대해 "대상 리소스에 요청 페이로드를 처리하도록 요구"하는 용도로 설계되었다고 설명합니다. 이는 POST 요청이 리소스의 상태를 변경할 수 있음을 의미하며, 이러한 이유로 POST 응답은 고유한 상황에 따라 달라질 수 있어 기본적으로 캐시하지 않는 것이 적절합니다.
  2. 캐시 가능성에 대한 명세 (RFC 7234): 캐싱에 관한 별도의 RFC 문서인 RFC 7234는 HTTP 응답이 언제 캐시될 수 있는지에 대한 더 구체적인 지침을 제공합니다. 이 문서는 특정 HTTP 메서드의 응답이 기본적으로 캐시 가능한지 여부를 설명하며, POST 요청에 대한 응답은 기본적으로 캐시 대상에서 제외됩니다. 하지만, 응답에 적절한 캐시 제어 헤더가 포함되어 있는 경우(예: Cache-Control 헤더)에 한해 예외적으로 캐시될 수 있음을 언급합니다.
  3. Varnish 공식 문서 및 베스트 프랙티스: Varnish Cache의 공식 문서와 베스트 프랙티스 가이드라인은 Varnish가 기본적으로 GET 및 HEAD 요청만 캐시하도록 구성되어 있으며, POST 및 기타 HTTP 메서드에 대한 요청은 캐시하지 않는다고 명시합니다. 이는 Varnish의 기본 동작과 관련된 명확한 지침을 제공합니다.

이러한 근거를 제시할 때, RFC 문서의 구체적인 절과 번호를 인용하거나, Varnish 공식 문서에서의 직접적인 설명을 참조하는 것이 좋습니다. 이를 통해 당신의 주장이 HTTP 프로토콜의 표준과 일치하며, 널리 인정된 캐싱 원칙에 기반하고 있음을 명확히 할 수 있습니다.

 

Varnish Cache에서 POST 요청이 캐시되지 않도록 코드를 명시하려면, Varnish의 기본 VCL(Varish Configuration Language) 설정 중 vcl_recv 부분을 참조할 수 있습니다. VCL은 Varnish가 요청을 어떻게 처리할지 결정하는 데 사용되는 설정 언어입니다. vcl_recv 함수는 클라이언트로부터 요청을 받았을 때 실행되며, 여기서 요청을 캐시할지, 바로 백엔드로 전달할지 등을 결정합니다.

 

아래는 Varnish가 POST 요청을 기본적으로 캐시하지 않도록 설정하는 vcl_recv 함수의 일반적인 예시입니다.

sub vcl_recv {
    # HTTP 메서드가 POST 또는 PUT일 경우 캐시하지 않음
    if (req.method == "POST" || req.method == "PUT") {
        return (pass);
    }
}

이 코드는 클라이언트 요청이 POST 또는 PUT 메서드를 사용하는 경우, 요청을 직접 백엔드로 전달하도록(return (pass);) 지시합니다. return (pass);는 Varnish가 해당 요청을 캐시 처리 대상에서 제외하고 바로 백엔드로 전송하도록 합니다. 이는 Varnish가 기본적으로 POST 및 PUT 요청을 캐시하지 않는다는 것을 명시적으로 보여줍니다.

 

Varnish 설정은 사용자의 특정 요구 사항에 따라 매우 다양하게 구성될 수 있기 때문에, 실제로 사용 중인 Varnish 버전의 기본 VCL 파일 또는 프로젝트에 맞춤화된 VCL 설정을 직접 확인하는 것이 가장 정확합니다. 기본 VCL 설정은 Varnish 설치 시 제공되며, Varnish 공식 문서나 소스 코드 저장소에서도 찾아볼 수 있습니다.

728x90

댓글