이시안 개발 블로그

HTTP 캐시와 조건부 동작 본문

📡Network

HTTP 캐시와 조건부 동작

ICAN 2021. 12. 14. 18:35

HTTP 헤더 캐시와 조건부 동작

1. 캐시가 없을 때

캐시가 없을 때 요청
캐시가 없을 때 재요청

  • 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다
  • 인터넷 네트워크는 매우 느리고 비싸다
  • 브라우저 로딩 속도가 느리다
  • 느린 사용자 경험

2. 캐시 적용

캐시 정보 전송

웹 브라우저에서 요청을 하면 서버에서 cache-control을 지정하는 방법으로 캐시를 적용할 수 있다.

캐시 저장

웹 브라우저의 캐시 저장소에 60초 동안 유효한 캐시 데이터를 저장한다.

캐시 유효 시간 검증
캐시로 조회

이후 웹 브라우저의 요청은 캐시에서 먼저 데이터를 조회하고 유효하다면 바로 가져올 수 있다.
이 때 캐시의 유효 시간이 초과되었다면 다시 서버로 요청을 보낸다.
응답 결과는 캐시 저장소에 새로 갱신한다.

  • 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다
  • 비싼 네트워크 사용량을 줄일 수 있다
  • 브라우저 로딩 속도가 매우 빠르다
  • 빠른 사용자 경험
  • 캐시 유효 시간이 초과하면 서버를 통해 다시 조회하고 캐시를 갱신한다.

검증 헤더

  • 캐시 만료 후에도 서버에서 데이터를 변경하지 않음
  • 데이터를 다시 전송받는 대신에 저장해 두었던 캐시를 재사용할 수 있다
  • 단 클라이언트와 서버의 데이터가 같은 지 확인할 수 있는 방법 필요

캐시 전송

서버가 응답을 보낼 때 검증 헤더에 최종 수정일을 저장할 수 있다.
응답 결과를 캐시에 저장할 때 검증 헤더의 최종 수정일 정보(Last-Modified)를 함께 저장한다.

캐시 수정일 확인

캐시 유효 시간이 초과되면 서버에 다시 요청을 보내는 데 캐시 데이터의 최종 수정일(if-modified-since)을 함께 보낸다.

응답 결과 재사용

서버에서 데이터 최종 수정일을 검증하여 변경되지 않았다면 304 Not Modified 응답을 한다.
이 때 HTTP Body 없이 보낸 응답 결과를 재사용하여 헤더 데이터와 캐시 데이터를 갱신하고 캐시에서 조회하게 된다.

정리

  • 캐시 유효 시간이 초과해도 서버의 데이터가 갱신되지 않으면
  • 304 Not Modified + 헤더 메타 정보만 응답(Body X)
  • 클라이언트는 응답 헤더 정보로 캐시 메타 정보를 갱신
  • 클라이언트는 캐시에 저장된 데이터를 재활용
  • 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드

매우 실용적인 해결책

캐시 정보 확인

크로미움 브라우저에서 네트워크를 선택해서 데이터가 캐시에서 불러온 것인지 확인할 수 있다.

검증 헤더와 조건부 요청

  1. 검증 헤더 (Validator)
    • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
    • Last-Modified, ETag
  2. 조건부 요청 헤더
    • 검증 헤더로 조건에 따른 분기
    • If-Modified-Since : Last-Modifed 사용
    • If-None-Match : ETag 사용
    • 조건이 만족하면 200 OK
    • 조건이 만족하지 않으면 304 Not Modified
  3. 예시
    • 데이터 미변경 예시
      • 캐시 : 2020년 11월 10일 10:00:00 vs 서버 : 2020년 11월 10일 10:00:00
      • 304 Not Modified, 헤더 데이터만 전송(Body 미포함)
      • 전송 용량 0.1M(헤더 용량만)
    • 데이터 변경 예시
      • 캐시 : 2020년 11월 10일 10:00:00 vs 서버 : 2020년 11월 10일 11:00:00
      • 200 OK, 모든 데이터 전송
      • 전송 용량 1.1M(헤더 0.1M + 바디 1.0M)

Last-Modified, If-Modified-Since

  • 1초 미만 단위로 캐시 조정이 불가능
  • 날짜 기반의 로직 사용
  • 데이터를 수정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 똑같은 경우
  • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
    • 예) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우

ETag, If-None-Match

  • ETag(Entity Tag)
  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
    • 예) ETag: "v1.0", ETag: "a2jiodwjekjl3"
  • 데이터가 변경되면 이 이름을 바꾸어서 변경함(Hash를 재생성)
    • 예) ETag: "aaaaa" -> ETag: "bbbbb"
  • 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기날짜 정보를 비교하고 확인하는 것보다 단순하고 쉬움
  • 캐시 제어 로직을 서버에서 완전히 관리
  • 클라이언트는 단순히 이 값을 서버에 제공

캐시 제어 헤더

  • Cache-Control
    • Cache-Control : max-age
      • 캐시 유효 시간, 초 단위
      • Cache-Control : no-cache
        • 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용
      • Cache-Control : no-store
        • 데이터에 민감한 정보가 있으므로 저장하면 안됨(메모리에서 사용하고 최대한 빨리 삭제)
  • Pragma(HTTP 1.0 하위 호환)
    • 잘 안씀
  • Expire(하위 호환)
    • 캐시 만료일을 날짜로 지정
    • 더 유연한 Cache-Control : max-age 권장

프록시 캐시

프록시 캐시 1

원래 소스가 있는 서버를 원 서버(origin)이라고 한다.
한국의 클라이언트가 미국의 원 서버를 조회하는 데 0.5초가 걸리는 것은 좋은 사용자 경험이 아니다.

프록시 캐시 2

네트워크의 시간 단축을 위해 한국에 프록시 캐시 서버를 만들고 DNS 요청을 조작해서 캐시 서버가 응답받게 한다.
유튜브나 넷플릭스 등의 서비스도 한국에 서버를 만들어서 운영하고 이런 방식으로 한국의 유저가 사용하게끔 하고 있다.
이 때 프록시 캐시 서버에 저장되는 캐시를 public 캐시, 개인 로컬에 저장되는 캐시를 private 캐시라고 한다.

기타 캐시 지시어

  • Cache-Control : public
    • 응답이 public 캐시에 저장되어도 됨
  • Cache-Control : private
    • 응답이 private 캐시에만 저장되어야 함(기본값)
  • Cache-Control : s-maxage
  • Age : 60(HTTP 헤더)

캐시 무효화

확실한 캐시 무효화 응답
이 정보는 절대 캐시가 되면 안된다할 때 전부 넣어야 한다.

  • Cache-Control : no-cache, no-store, must-revalidate
  • Cache-Control : must-revalidate
    • 캐시 만료 후 최초 조회 시 원 서버에 검증해야 함
    • 원 서버 접근 실패 시 반드시 오류가 발생해야 함- 504 Gateway Timeout
    • 캐시 유효 시간이라면 캐시를 사용함
  • Pragma : no-cache
    • HTTP 1.0 하위 호환

no-cache

no-cache는 캐시를 사용하지만 프록시 캐시 서버가 아닌 origin 서버에서 항상 검증을 받아야 한다.
하지만 몇몇의 서비스는 프록시 캐시 서버와 origin 서버 간의 이슈가 발생했을 때 캐시 서버의 설정에 따라 에러 또는 오래된 데이터를 보여주기도 한다.

must-revalidate

must-revalidate는 항상 origin 서버에 검증을 받되 origin 서버에 접근할 수 없는 경우 무조건 오류를 발생해야 한다.
504 응답 코드를 반환해야 하며 캐시에 저장을 막을 때 꼭 같이 써줘야 하는 이유이다.

출처: 모든 개발자를 위한 HTTP 웹 기본 지식

'📡Network' 카테고리의 다른 글

HTTP 헤더  (0) 2021.12.12
HTTP 메서드와 활용  (0) 2021.12.10
HTTP 기본  (0) 2021.12.09
URI와 웹 브라우저 요청 흐름  (0) 2021.12.07
인터넷 네트워크  (2) 2021.12.04
Comments