[스프링 Web Servlet 공식문서 읽기]1. Spring MVC (9) HTTP Caching

ybw·2022년 1월 15일

1.9 HTTP Caching

HTTP 캐싱은 웹 애플리케이션의 성능을 크게 향상시킬 수 있습니다. HTTP 캐싱은 Cache-Control 응답 헤더와 조건부 요청 헤더(예: Last-ModifiedETag)를 중심으로 이루어집니다. Cache-Control은 응답을 캐시하고 재사용하는 방법에 대해 개인(예: 브라우저) 및 공용(예: 프록시) 캐시에 조언 합니다. ETag 헤더는 내용이 변경되지 않은 경우 본문 없이 304(NOT_MODIFIED)가 발생할 수 있는 조건부 요청을 수행하는 데 사용됩니다. ETagLast-Modified 헤더의 보다 정교한 후계자로 볼 수 있습니다.

이 섹션에서는 Spring Web MVC에서 사용할 수 있는 HTTP 캐싱 관련 옵션에 대해 설명합니다.

1.9.1 CacheControl

CacheControlCache-Control 헤더와 관련된 설정 구성을 지원하며 여러 위치에서 인수로 허용됩니다.

RFC 7234Cache-Control 응답 헤더에 대한 모든 가능한 지시문을 설명하지만 CacheControl 유형은 일반적인 시나리오에 중점을 둔 사용 사례 중심 접근 방식을 취합니다.

// Cache for an hour - "Cache-Control: max-age=3600"
CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS);

// Prevent caching - "Cache-Control: no-store"
CacheControl ccNoStore = CacheControl.noStore();

// Cache for ten days in public and private caches,
// public caches should not transform the response
// "Cache-Control: max-age=864000, public, no-transform"
CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic();

WebContentGenerator는 다음과 같이 작동하는 더 간단한 cachePeriod 속성(초 단위로 정의됨)도 허용합니다.

  • -1 값은 Cache-Control 응답 헤더를 생성하지 않습니다.

  • 0 값은 'Cache-Control: no-store' 지시문을 사용하여 캐싱을 방지합니다.

  • n > 0 값은 'Cache-Control: max-age=n' 지시문을 사용하여 n초 동안 주어진 응답을 캐시합니다.

1.9.2 Contollers

컨트롤러는 HTTP 캐싱에 대한 명시적 지원을 추가할 수 있습니다. 리소스에 대한 lastModified 또는 ETag 값이 조건부 요청 헤더와 비교되기 전에 계산되어야 하므로 그렇게 하는 것이 좋습니다. 컨트롤러는 다음 예제와 같이 ResponseEntityETag 헤더 및 Cache-Control 설정을 추가할 수 있습니다.

@GetMapping("/book/{id}")
public ResponseEntity<Book> showBook(@PathVariable Long id) {

    Book book = findBook(id);
    String version = book.getVersion();

    return ResponseEntity
            .ok()
            .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
            .eTag(version) // lastModified is also available
            .body(book);
}

앞의 예는 조건부 요청 헤더와 비교하여 콘텐츠가 변경되지 않았음을 나타내는 경우 빈 본문과 함께 304(NOT_MODIFIED) 응답을 보냅니다. 그렇지 않으면 ETagCache-Control 헤더가 응답에 추가됩니다.

다음 예제와 같이 컨트롤러의 조건부 요청 헤더에 대해 확인할 수도 있습니다.

@RequestMapping
public String myHandleMethod(WebRequest request, Model model) {

    long eTag = ... // (1)

    if (request.checkNotModified(eTag)) {
        return null;  // (2)
    }

    model.addAttribute(...); // (3) 
    return "myViewName";
}
  1. 애플리케이션별 계산

  2. 응답이 304(NOT_MODIFIED) - 추가 처리 없음으로 설정되었습니다.

  3. 요청 처리를 계속합니다.

eTag 값, lastModified 값 또는 둘 다에 대해 조건부 요청을 확인하기 위한 세 가지 변형이 있습니다. 조건부 GETHEAD 요청의 경우 응답을 304(NOT_MODIFIED)로 설정할 수 있습니다. 조건부 POST, PUTDELETE의 경우 대신 응답을 412(PRECONDITION_FAILED)로 설정하여 동시 수정을 방지할 수 있습니다.

1.9.3 Static Resources

최적의 성능을 위해 Cache-Control 및 조건부 응답 헤더와 함께 정적 리소스를 제공해야 합니다. Static Resource 구성에 대한 섹션을 참조하세요.

1.9.4 ETag Filter

ShallowEtagHeaderFilter를 사용하여 응답 내용에서 계산되는 "얕은" eTag 값을 추가할 수 있으므로 CPU 시간이 아닌 대역폭을 절약할 수 있습니다. Shallow ETag를 참조하십시오.

profile
유병우

0개의 댓글