[인강노트-웹지식] 7. HTTP 헤더2 - 캐시와 조건부 요청

봄도둑·2022년 5월 17일
0

김영한님의 모든 개발자를 위한 HTTP 웹 기본 지식 강의 내용을 정리한 노트입니다. 블로그에 있는 자료를 사용하실 때에는 꼭 김영한님 강의 링크를 남겨주세요!

1. 캐시의 기본 동작

1-1. 캐시를 사용하지 않는다면...

  • 동일한 요청이 2번 내려가게 됨
  • 위의 이미지에서 응답으로 총 1.1M가 내려갔는데 2번째 요청 시 동일한 데이터가 1.1M가 또 응답으로 나감
  • 즉, 데이터가 변경되지 않았더라도 계속 네트워크를 통해서 동일한 데이터를 다운 받아야함
  • 인터넷 네트워크는 매우 느리고 비쌈 → 브라우저의 로딩 속도가 느려짐 → 느리고 부정적으로 바뀌는 사용자 경험을 만들게 됨

1-2. 캐시 동작

  • 클라이언트는 요청을 통해 받은 응답을 캐시에 저장하게 됨
  • 이후 동일한 요청을 클라이언트에서 보낼 때, 캐시의 유효성 검증 후 서버를 통해 응답을 받는 것이 아니라 캐시를 가져다 쓰게 됨
  • 이를 통해 캐시가 가능한 시간 동안 느리고 비싼 네트워크를 사용하지 않아도 됨
  • 그로 인해 개선되는 빠른 사용자 경험을 만들 수 있음
  • 만약 캐시의 유효한 시간이 다 끝났을 경우(헤더에서 지정한 cache-control: max-age=60 ) 서버를 통해 다시 응답 결과를 받고 해당 응답을 캐시에 다시 저장하게 됨
  • 그런데, 이 때 다시 네트워크 다운로드의 비용이 발생하는데, 바뀌지 않은 동일한 데이터를 받을 때 이미 가지고 캐시 데이터인데 굳이 다시 서버를 통해 받을 필요가 있을까? ⇒ 그래서 등장한 검증 헤더와 조건부 요청!

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

2-1. 캐시의 재사용 로직

  • 우리는 동일한 데이터가 유효 시간이 지났다고 못 쓰는 것 보다 다시 사용하고 싶음 → 데이터를 전송하는 대신에 저장해 두었던 캐시를 재사용할 것 → 그 전에, 클라이언트의 캐시 데이터와 서버가 내려줄 데이터가 같다는 검증이 선행되어야 함
  • 서버에서 데이터를 내려줄 때 헤더에 현재 내려주는 데이터의 최종 수정일 정보(Last-Modified)를 헤더에 같이 내려줌
  • 이후 클라이언트가 서버에 요청을 보낼 때 if-modified-since(캐시에 저장된 데이터의 최종 수정일 정보)를 헤더에 넣어서 보냄
  • 이후 클라이언트는 최종 데이터 수정일을 비교 후, 두 개의 정보가 같다면 304 Not Modified를 응답으로 내려줌. 이 때의 응답에 http body는 따로 나가지 않음 → 클라이언트는 캐시 데이터가 안 바뀌었으니 써도 되는 것으로 인식, 캐시 데이터를 다시 세팅하고 불러와서 사용
  • 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드
  • 크롬 개발자 도구(f12)로 볼 때 회색 배경으로 응답이 내려온 건 캐시로 내려온 데이터
  • 검증 헤더 : 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터 ex)Last-Modified, ETag
  • 조건부 요청 헤더 : 검증 헤더로 조건에 따른 분기
    • 조건이 만족하면 200 OK
    • 조건이 만족하지 않으면 304 Not Modified → 너의 캐시로 리다이렉션 해라 라는 의미

2-2. Last-Modified

  • If-Modified-Since와 같이 사용
  • 날짜 기반의 로직 사용 → 1초 미만(0.~초) 단위로 캐시 조정이 불가능
  • 만약 데이터가 A → B → A로 데이터 수정 시, 데이터는 그대로지만 날짜는 변경됨 ⇒ 서버 입장에서는 변경된 데이터라고 인식

2-3. ETag

  • Last-Modified의 단점
    • 만약 데이터가 A → B → A로 데이터 수정 시, 데이터는 그대로지만 날짜는 변경됨 ⇒ 서버 입장에서는 변경된 데이터라고 인식
    • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 ex) 스페이스나 주석처럼 데이터의 크게 영향을 미치지 않는 변경에서 캐시를 유지하고 싶은 경우

ETag (Entity Tag)

  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
  • 데이터가 변경되면 ETag의 이름을 바꾸어서 변경
  • 단순하게 ETag가 같으면 캐시, 다르면 새로운 데이터를 내려주면 됨
  • ETag를 사용하면 클라이언트는 캐시의 로직을 전혀 몰라도 ETag만 있으면 캐시 여부를 서버에 보내 확인할 수 있음

3. Cache-Control

  • Cache-Control은 캐시 제어 헤더
  • Cache-Control: max-age
    • 캐시의 유효 시간으로 초 단위로 지정
  • Cache-Control: no-cache
    • 데이터는 캐시해도 되지만, 항상 원서버(origin) 서버에서 검증 후 사용할 것
  • Cache-Control: no-store
    • 캐시를 저장하면 안됨(메모리에서 사용하고 최대한 빨리 삭제할 것)
  • Pragma와 expires → Cache-Control과 동일한 기능을 수행하지만 HTTP 1.0 하위호환으로만 동작 → 옛날 거여서 안씀

4. 프록시 캐시

  • 웹 브라우저들이 미국에 있는 원 서버에 접근 시 속도가 많이 느림 → 이 때 중간에 프록시 캐시 서버를 둬서 미국에 있는 원 서버에서 데이터를 받아오는 것이 아니라 캐시 서버에서 데이터를 받아오도록 지정
  • 이렇게 프록시 캐시 서버에 저장된 캐시를 public cache, 웹 브라우저의 로컬에 저장되어 있는 캐시를 private cache라고 부름
    • private cache는 해당 사용자만을 위한 것
  • 이렇게 프록시 캐시가 되어 있어서 우리가 유튜브를 볼 때 빠른 속도로 볼 수 있는 것
    • 미국에 있는 원서버에서 인기가 많은 외국 동영상들을 한국 프록시 캐시 서버에 올림 → 그럼 우리는 인기가 많은 외국 동영상을 볼 때 원 서버에서 응답으로 내려오는 동영상이 아니라 한국 프록시 캐시 서버에 있는 동영상을 빠른 속도로 볼 수 있는 것

5. 캐시 무효화

  • 캐시 무효화 응답을 하기 위해서는 아래와 같은 녀석들이 함께 쓰임

    • Cache-Control: no-cache, no-store, must-revalidate + Pragma: no-cache
    • Pragma를 사용하는 이유는 아주 낮은 버전의 http에서 접근했을 경우를 대비해 같이 쓰임 → 구글같은 글로벌 웹사이트에서 사용
  • Cache-Control: must-revalidate

    • 캐시 만료 후 최초 조회 시 원 서버에 검증해야함 → 어, 근데 이거 no-cache와 같은 거 아님?
    • no-cache는 원 서버가 순간 접근 불가 상태가 되었을 때, 과거 데이터로 응답을 임의로 해버릴 수 있음
    • 반면, must-revalidate는 원 서버가 접근 불가 상태가 되었을 때 응답을 504 Gateway Timeout을 응답함
    • 통장 잔고를 생각해보면 → 원 서버의 내 원래 잔고 정보가 아니라 과거 내 잔고 정보가 내려온다고 생각하면 504로 응답해 아예 잔고 정보를 그려주지 않도록 만드는 것

블로그에 있는 자료를 사용하실 때에는 꼭 김영한님 강의 링크를 남겨주세요!
(강의 링크 : https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard)

profile
배워서 내일을 위해 쓰자

0개의 댓글