8. HTTP 헤더2 - 캐시와 조건부 요청

KOO HEESEUNG·2021년 10월 8일
post-thumbnail

이 포스팅은 인프런 김영한 강사님의 <모든 개발자를 위한 HTTP 웹 기본 지식>을 수강하고, 공부하여 글로 정리한 것입니다. 그대로 갖다 붙여넣는 내용이 아니라 기억나는대로 작성한 후 다시 추가적으로 정리하는 방식을 취하고 있기 때문에 틀린 부분이 있을 수 있습니다. 잘못된 점은 짚어주시면 감사하겠습니다.

1. 캐시 기본 동작

1-1. 캐시가 없을 때

데이터가 변경되지 않아도 계속 네트워크를 통해 데이터를 다운로드 받아야 하는데, 인터넷 네트워크는 매우 느리고 비싸다. 브라우저 로딩 속도가 느려서 느린 사용자 경험을 할 수밖에 없음.

1-2. 캐시 적용

cache-control (캐시가 유효한 시간) 을 응답 헤더에 입력하여 전달한다.

웹 브라우저 내부에는 캐시를 저장하는 저장소가 있어서 여기에 응답 결과를 저장한다. (이후부터는 캐시에서 먼저 조회하여 가져옴)

장점

캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 되므로, 비싼 네트워크 용량을 줄일 수 있다. 브라우저 로딩 속도가 매우 빨라 빠른 사용자 경험이 가능하다.

1-3. 캐시 시간 초과

캐시 유효시간이 초과하면, 서버를 통해 데이터를 다시 조회하고 캐시를 갱신한다. 이때 다시 네트워크 다운로드가 발생한다.

그런데 캐시 만료 후에도 서버에서 데이터를 변경하지 않았는데도 새로 받아오는 것은 바람직하지 않다. => 이를 해결하기 위해 나온 것이 검증 헤더와 조건부 요청


2. 검증 헤더와 조건부 요청 1

데이터를 전송하는 대신 저장해두었던 캐시를 재사용할 수 있다. 단, 클라이언트 데이터와 서버 데이터가 같다는 사실을 확인할 방법이 필요.

검증 헤더 추가

응답 헤더에 Last-Modified (데이터 최종 수정일) 필드를 추가.

캐시가 만료되어 서버에 요청을 보낼 때 if-modified-since 필드에 데이터 최종 수정일 값을 넣어서 전송하여 데이터의 변동 여부를 검증.

변동이 없으면 응답 상태코드로 304 Not Modified 전송. HTTP Body가 없다.

결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드하여 부하가 줄어듦.


3. 검증 헤더와 조건부 요청 2

  • 검증 헤더
    • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터.
    • Last-Modified, ETag
  • 조건부 요청 헤더
    • 검증 헤더로 조건에 따른 분기를 서버에 요청
    • If-Modified-Since: Last-Modified와 함께 사용
    • If-None-Match: ETag와 함께 사용
    • 조건 만족시 200 OK
    • 조건 만족하지 않으면 304 Not Modified

ETag, If-None-Match

Last-Modified , If-Modified-Since는 1초 미만 단위로 캐시 조정이 불가능하다는 단점이 존재한다.

또한 날짜 기반의 로직을 사용해서 만약 데이터를 수정해서 Last-Modified 날짜는 다르지만 데이터 결과가 똑같은 경우에는 ETag를 사용한다.

  • ETag(Entity Tag)

  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
    예) ETag: "v1.0"

  • 데이터 변경되면 이 이름을 바꾸어서 변경(Hash 다시 생성)
    예) ETag: "aaaaa" -> ETag: "bbbbb"

  • ETag만 보내서 같으면 유지, 다르면 다시 받기

  • 캐시 제어 로직을 서버에서 완전히 관리. 클라이언트는 캐시 메커니즘을 모름.(단순히 이 값을 서버에 제공)


4. 캐시와 조건부 요청 헤더

4-1. 캐시 제어 헤더

Cache-Control

  • Cache-Control: max-age
    캐시 유효시간, 초단위
  • Cache-Control: no-cache
    데이터는 캐시해도 되지만, 항상 origin 서버에 검증 후 사용
  • Cache-Control: no-store
    데이터에 민감한 정보가 있으므로 저장하면 안됨(메모리에서만 사용하고 최대한 빨리 삭제)

Pragma

  • Pragma: no-cache
  • HTTP 1.0 하위 호환이므로, 현재는 거의 사용되지 않음.

Expires

  • 캐시 만료일을 정확한 날짜로 지정
  • 지금은 더 유연한 Cache-Control: max-age를 권장하므로, 둘이 함께 사용하면 Expires는 무시됨

4-2. 검증 헤더와 조건부 요청 헤더

검증 헤더 (Validator)

  • ETag, Last-Modified

조건부 요청 헤더

  • If-Match, If-None-Match: ETag값 사용
  • If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용

5. 프록시 캐시

클라이언트에서 원 서버에 직접 접근하는 것이 아닌, 중간에 프록시 캐시 서버를 두어 이를 거쳐 접근할 수 있도록 한다.

Cache-Control

  • public
    응답이 public 캐시에 저장되어도 됨
  • private
    응답이 해당 사용자만을 위한 것. private 캐시에 저장해야 함(기본값)
  • s-maxage
    프록시 캐시에만 적용되는 max-age
  • Age: 60 (HTTP 헤더)
    오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)

6. 캐시 무효화

확실한 캐시 무효화 응답을 위해

  • Cache-Control: no-cache, no-store, must-revalidate
  • HTTP 1.0 하위호환을 위해 Pragma: no-cache

까지 모두 넣어준다.

  • must-revalidate : 캐시 만료 후 최초 조회시 원 서버에 검증해야 함. 원서버 접근 실패시 반드시 오류 발생해야 함(504 Gateway Timeout). 캐시 유효시간이라면 캐시를 사용함.

no-cache vs must-revalidate

  • no-cache : 원서버에 접근할 수 없는 경우, 캐시 서버 설정에 따라 캐시 데이터 반환 가능. 오류 또는 오래된 데이터라도 반환.
  • must-revalidate : 원서버에 접근할 수 없는 경우, 항상 오류 발생.

0개의 댓글