[HTTP] HTTP 헤더2 - 캐시와 조건부 요청

이건회·2022년 6월 20일
0

HTTP

목록 보기
16/16

  • 캐시의 동작 과정에 대해 알아보도록 하겠다.

  • 캐시가 없을 때 이미지를 요청하면 서버에서 이미지를 찾아 응답한다. 헤더 밑에 이미지 관련 바이트 코드가 있으며, 헤더와 바디를 합쳐 1.1m의 데이터가 넘어온다

  • 그럼 요청한 이미지가 웹 브라우저에 표시된다.


  • 캐시가 없을 때 같은 요청을 또 보내면? 역시 같은 양의 데이터를 다시 보낸다

  • 캐시가 없으면 데이터가 변경되지 않아도 계속 네트워크를 통해 데이터를 다운로드 받아야 하므로 느려진다.

  • 캐시를 적용한 버전에서는 헤더에 "캐시 컨트롤" 항목을 집어넣어 캐시가 유효한 시간을 표시한다. 여기서는 60초동안 캐시를 유효하게 만든다.
  • 브라우저 캐시에 응답 결과를 저장하고 60초간 유효하게 한다.

  • 따라서 두 번째 요청이 오면 일단 브라우저 캐시를 뒤지고, 해당 데이터가 있고 유효 시간이 확인되면 곧바로 캐시에서 가져온다.

  • 따라서 캐시의 이점은 빠르고 네트워크 사용량이 줄어든다는 점이다


  • 그러나 세 번째 요청에서 60초 초과로 캐시 시간이 초과되면 다시 요청을 해야 한다. 그러면 서버는 다시 60초 유효한 캐시를 내려준다.

  • 받은 캐시 데이터를 다시 저장해 초기화한다

  • 캐시 유효 시간이 초과하면 서버를 통해 데이터를 항상 조회하고 캐시를 갱신해야 한다.


  • 만약 캐시가 만료 되었어도 클라이언트의 데이터와 서버의 데이터가 변경이 없으면, 또 받아야 하는 건 낭비가 아닐까?

  • 따라서 데이터 전송 대신 저장해 두었던 캐시를 재사용 하는 방법을 생각할 수 있다.
  • 클라이언트/서버의 데이터가 바뀌지 않았음을 확인 해야 한다. 이것이 검증 헤더다!

  • "last-modified"라는 헤더를 추가하여 데이터가 마지막에 수정된 시간을 명시해 서버가 응답을 보낸다.
  • 브라우저 캐시는 이 결과를 함께 저장한다.

  • 유효시간인 60초가 지나면, 브라우저 캐시는 데이터 최종 수정일 값을 "if-modified-since" 헤더에 포함해 서버에 보낸다.

  • "if-modified-since가 오면 서버는 해당 데이터의 최종 수정일을 비교하고 검증한다!

  • 수정이 안됐을 경우, 서버는 304 not modified라는 응답을 보낸다. 중요한 것은 이때 http body가 없다. 수정 된 것이 없기 때문이다. 따라서 네트워크 부하가 확 준다.
  • 이를 확인한 브라우저는 응답 결과를 사용해 유효기간을 갱신한다.

  • 따라서 정상적으로 캐시를 재사용한다.

  • 따라서 서버 데이터 갱신이 없으면 304와 함께 헤더 메타 정보만 응답하므로, 용량이 적은 헤더 정보만 다운로드해 매우 실용적이다.

  • 검증 헤더는 캐시와 서버 데이터가 같은지 검증한다.
  • 조건부 요청은 검증 헤더로 조건에 따라 분기를 서버에 요청한다.

  • 이후에 데이터가 수정되었으면 200 ok를 보내고 모든 데이터를 전송한다, 수정되지 않았으면 304 not modified로 응답하고 헤더만 전송한다.

  • 그러나 단점은 1초 미만 단위로 캐시 조정이 불가능하며, 날짜 기반으로 로직을 사용하므로, 수정한 결과가 똑같아도 날짜가 다를 수 있다(예를 들어 A를 B로 바꿨다가 다시 A로 바꿈). 이 경우에도 전체 데이터를 다시 전송하게 된다.

  • 캐시 데이터에 임의 버전 이름인 ETAG을 달아두어, 단순히 이 태그만 같으면 유지, 다르면 다시 받도록 하여 원본 데이터가 같기만 하면 날짜가 달라도 ETAG가 같으므로 위 문제를 해결할 수 있다.

  • 요청을 하면 서버가 etag로 응답하고 서버가 이 값을 저장한다.

  • 시간 초과가 발생하고, 브라우저가 etag로 조건부 요청을 보낸다.

  • etag 확인을 통해 데이터가 수정되지 않았음을 확인한다.


  • 따라서 304 not modified를 응답하고 응답 결과를 재사용한다.

  • 이를 통해 캐시 제어 로직을 서버에서 완전히 관리할 수 있다.

  • 캐시 제어와 관련된 다음과 같은 헤더들이 있다

  • 캐시 컨트롤은 가장 많이 사용하는 것이다.
  • max-age는 캐시의 유효시간을 초 단위로 지정한다.
  • no-cache 데이터는 캐시해도 되지만, 항상 캐시를 쓰기 전에 조건부 요청을 통해 원 서버에 변경 검증을 해야 한다.
  • no-store는 데이터에 민감한 정보가 있어 저장하면 안된다는 뜻이다.

  • Pragma: no-cache는 위와 같다

  • Expires는 캐시 만료일을 지정하는 하위호환 방법이다.
  • 지금은 더 유연한 캐시 컨트롤의 max-age를 권장한다.

  • 검증 헤더는 etag와 last-modified
  • 조건부 요청 헤더는 if-match,if-modified-since 등이 있다.

  • 한국 클라이언트가 미국 원 서버까지 가는 시간이 0.5초가 걸린다고 했을 때

  • 프록시 서버라는 것을 한국 어딘가에 두어 요청을 처리하면 더 빠르게 처리할 수 있다.
  • 프록시 서버의 캐시를 public 캐시, 웹 브라우저의 캐시를 private 캐시라 한다.

  • 따라서 캐시 컨트롤에서 public을 지정하면 public 캐시에 저장되도 된다는 뜻이다. private은 private에만 저장해야 하는 것이다.

  • 캐시를 무효화할 수 있는 응답이 캐시 컨트롤에 있다.
  • 절대 캐시되서는 안 되는 페이지(통장 잔고 정보 등)가 있다면, Cache-Control: no-cache, no-store, must-revalidate를 다 넣어주어야 한다.

  • must-revalidate는 캐시 만료 후 최초 조회시 반드시 원 서버에 검증해야 하는 것이다.


  • 만약 no cache로 요청을 보내고 프록시 서버에서 이를 확인 후 원 서버로 보내려는데 순간적으로 원 서버로 가는 길이 단절되면 가끔 프록시 서버의 설정에 따라 프록시 캐시가 오류를 내지 않고 이전 데이터를 보내도록 하는 경우가 있다.

  • 그러나 must-revalidate 옵션을 넣는 순간 서버 설정에 상관 없이 원서버에 접근할 수 없는 경우 항상 504 gateway timeout 오류가 발생한다.
profile
하마드

0개의 댓글