본문 바로가기
Computer Science/Network

[Network] HTTP 웹 기본 지식 - 8. HTTP 헤더 (캐시와 조건부 요청)

by pilgyeong 2023. 2. 10.

 

 

1. 캐시 기본 동작

기본적으로 캐시를 사용할 경우, 첫 번째 요청에서 'cache-control: max-age=n'을 넣어서 응답한 뒤에, 두 번째 요청에서는 먼저 브라우저 캐시를 살펴본다. 유효한 시간 안에 있다면, 브라우저 캐시로부터 바로 조회하기 때문에 응답 속도가 빨라진다.

 

캐시를 적용했을 때 다음의 장점이 존재한다.

  • 캐시 가능 시간 내에서는 네트워크를 사용하지 않아도 되므로, 네트워크 사용량을 줄일 수 있다.
  • 브라우저 로딩 속도가 매우 빨라 사용자 경험이 개선된다.

그러나, 캐시 유효시간이 초과된 경우, 다시 네트워크를 사용하여 서버를 통해 캐시를 갱신하게 된다. 이때, 다시 네트워크 다운로드가 발생한다.

 

 

 

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

캐시 유효시간이 초과해서 다시 서버에서 다운로드 받아올 때, 2가지 경우의 수가 생긴다.

  1. 서버에서 기존 데이터를 변경하지 않은 경우
  2. 서버에서 기존 데이터를 변경한 경우

 

2.1 서버에서 기존 데이터를 변경하지 않은 경우

만약에 서버에서 기존 데이터를 변경하지 않았다면, 기존에 브라우저 캐시에 저장해둔 데이터를 재사용하면 효율적이다. 단, 클라이언트가 캐시에 저장한 데이터가 서버의 데이터와 같다는 사실을 검증하는 방법이 필요하다.

  • 애초에 첫 번째 요청에서 검증용 헤더(Last-Modified: XXXXXX)를 삽입해서 응답한다. 이후, 캐시 유효시간 초과로 서버에 재요청을 할 때, Last-Modified를 확인해서 동일하다면 아직 데이터가 변경되지 않았다는 것이다.
  • 그러면 서버는 304 Not Modified 상태코드와 함께 HTTP Body 없이 응답한다. 즉, 응답하는 서버는 '헤더 정보'를 통해 메타 정보를 갱신시킨다. 응답을 받은 클라이언트는 캐시에 저장되어 있는 데이터를 재활용한다.
  • 결국, 네트워크 다운로드가 발생하긴 하지만, 매우 적은 용량인 헤더 정보만 다운로드 하기 때문에 실용적인 방법이 된다.

 

2.2 서버에서 기존 데이터를 변경한 경우

Last-Modified를 확인해서 동일하지 않게 되므로, 새로운 응답(헤드 정보, 메세지 바디)을 담아 메타 정보를 갱신하게 된다. (그냥 새로 다운로드 받는 것과 동일함)

 

 

 

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

검증 헤더

  • 캐시에 저장된 데이터와 서버의 데이터가 같은지 검증하기 위한 데이터
  • Last-Modified, ETag

조건부 요청 헤더

  • 검증 헤더로 조건에 따른 분기
  • If-Modified-Since: Last-Modified를 사용
  • If-None-Match: ETag를 사용
  • 조건이 만족하면 '200 OK' 응답
  • 조건이 만족하지 않으면 '304 Not Modified' 응답 (은근 헷갈림 주의 필요)

 

Last-Modified, If-Modified-Since 단점

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

 

ETag, If-None-Matc

  • ETag (Entity Tag)
  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아준다.     (ex) ETag: "v1.0"
  • 데이터가 변경되면, 이 이름을 바꿔서 변경한다. (Hash 재생성)     (ex) ETag: "A" -> ETag: "B"
  • 진짜 단순하게 ETag만 보내서 같으면 유지하고, 다르면 다시 응답 받음

 

ETag가 같으면 유지하고, 다르면 다시 받는다. 캐시 제어 로직을 서버에서 완전히 분리시킨 방법이 된다.

클라이언트는 단순히 이 값을 서버에 제공(클라이언트는 캐시 메커니즘을 모른다)

  • 서버는 배타 오픈기간인 3일 동안 파일이 변경되어도 ETag를 동일하게 유지한다.
  • 애플리케이션 배포 주기에 맞춰 ETag를 모두 갱신하는 방법으로 검증한다.

 

 

 

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

4.1 Cache-Control: 캐시 제어

캐시 지시어(directives) - 캐시 제어

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

 

4.2 Pragma: 캐시 제어 (하위 호환)

캐시 제어

  • Pragma: no-cache
  • HTTP 1.0 하위 호환

 

4.3 Expires: 캐시 유효 기간 (하위 호환)

캐시 만료일 지정

  • 캐시 만료일을 정확한 날짜로 지정해주는 방식
  • HTTP 1.0 부터 사용되었지만, 지금은 더 유연한 "Cache-Control: max-age" 사용을 권장함
  • "Cache-Control: max-age"와 함께 사용되면, Expires는 무시함

 

 

 

5. 프록시 캐시

중간에 프록시 캐시 서버를 두고, 자주 사용되는 내용을 저장하고 바로 응답해주는 방식

 

캐시 지시어(directives) - 기타

  • "Cache-Control: public" : 응답이 public 캐시에 저장되어도 됨          
  • "Cache-Control: private" : 응답이 해당 사용자만을 위한 것임 (private 캐시에 저장하는 것이 default)
  • "Cache-Control: s-maxage" : 프록시 캐시에만 적용되는 max-age
  • "Age: 60" (HTTP 헤더) : 원 서버에서 응답 후 프록시 캐시 내에 머문 시간(초 단위)                 

 

6. 캐시 무효화

캐시 지시어(directives) - 확실한 캐시 무효화

  • "Cache-Control: no-cache" : 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용함
  • "Cache-Control: no-store" : 데이터에 민감한 정보가 있으므로 저장하면 안 됨 (메모리에서 사용 후 곧바로 삭제)
  • "Cache-Control: must-revalidate" : 캐시 만료 후 최초 조회 시 원 서버에 검증해야 되며, 원 서버에 접근 실패 시 오류가 발생(504 Gateway Timeout)해야 된다. (캐시 유효 시간 내에 있다면 캐시를 사용함)

 

원 서버에 접근 실패 시

  • no-cache : 200 OK (오류 보다는 오래된 데이터라도 보여줄 때)
  • must-revalidate : 504 Gateway Timeout (중요한 내용이기 때문에 오래된 데이터라도 보여주지 않아야 될 때)

 

 

 


출처.

https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com