HTTP Caching

de_sj_awa·2021년 7월 5일
0
post-custom-banner

HTTP 캐싱은 웹 어플리케이션의 성능을 크게 향상시킬 수 있다. HTTP 캐싱은 Cache-Control 응답 헤더나 Last-Modified 요청 헤더나 ETag 요청 헤더의 결합으로 이루어진다. Cache-Control 응답 헤더는 어떻게 캐싱하고 응답을 재사용할지 명시한다. ETag 헤더는 만약에 응답 내용이 변경되지 않는 경우, 본문이 없는 304(NOT_MODIFIED) 응답을 만들기 위한 조건적인 요청을 보낼 때 사용한다. ETtag 헤더는 Last-Modified 헤더보다 더 정교하게 설정할 수 있게 해준다.

1. CacheControl

CacheControl은 Cache-Control 헤더 설정을 할 수 있게 해주며, 다음과 같은 위치에서 매개변수로 사용할 수 있다.

  • WebContentInterceptor
  • WebContentGenerator
  • Controllers
  • Static Resources
// 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'을 사용하여 몇 초 동안 응답을 캐싱할지 설정한다.

2. Controllers

컨트롤러는 HTTP 캐싱에 대한 설정을 할 수 있다. 또한 컨트롤러는 Last-Modified 요청 헤더 또는 ETag 요청 헤더와 비교하여 계산할 수 있다. 다음의 예제는 컨트롤러가 ResponseEntity에 ETag 헤더와 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);
}

위의 예는 조건부 요청 헤더(Etag 헤더)와 비교해서 콘텐츠가 변경되지 않았음을 명시할 경우 본문이 없는 304(NOT_MODIFIED) 응답을 보내는 경우를 보여준다. 그렇지 않으면, ETag나 Cache-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 요청 헤더와 Last-Modified 요청 헤더를 각각 체크하거나 둘 다 체크할 수도 있다. 또한 GET, HEAD 요청에 대해서는 응답을 304(NOT_MODIFIED)로 설정할 수 있으며 POST, PUT, DELTETE 요청에 대해서는 동시 수정을 방지하기 위해 응답을 412 (PRECONDITION_FAILED)로 설정할 수 있다.

참고

profile
이것저것 관심많은 개발자.
post-custom-banner

0개의 댓글