본문 바로가기
개발자 일지/네트워크

[인프런 김영한 로드맵3]모든 개발자를 위한 HTTP 웹 기본 지식3

by 네빌링 2022. 9. 1.
반응형

- 김영한님의 인프런강의 '모든 개발자를 위한 HTTP 웹 기본 지식'을 학습하고 정리한 내용이다.

- HTTP 웹 기본 지식과 관련된 내용을 학습힌다.

- 모든 내용 및 이미지 출처는 인프런 및 김영한님에게 있습니다.

- 이전 글은 아래 링크를 클릭해주세요.

 

 

[인프런 김영한 로드맵3]모든 개발자를 위한 HTTP 웹 기본 지식2

- 김영한님의 인프런강의 '모든 개발자를 위한 HTTP 웹 기본 지식'을 학습하고 정리한 내용이다.- HTTP 웹 기본 지식과 관련된 내용을 학습힌다.- 모든 내용 및 이미지 출처는 인프런 및 김영한님에

roadofdevelopment.tistory.com

 


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

 

1.캐시 기본 동작

 

캐시가 적용되는 흐름은 다음과 같은 예시가 있다. 이미지파일을 요청하고 받는 경우다.

 

  • 웹브라우저에서 GET /star.jpg요청
  • 서버에서 star.jpg를 내려주는데 응답헤더에 Cache-Control:max-age=60을 담아서 전송
  • 브라우저 캐시에 응답 결과를 저장(60초 유효)
  • 2번째 요청시 캐시가 유효한지 확인 후 유효하다면 브라우저 캐시에 GET /star.jpg 요청(유효하지 않으면 다시 서버로 요청)

 

캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 되고 네트워크 사용량을 줄일 수 있다. 또한 브라우저 로딩 속도도 빠르다.

 

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

 

서버의 원본 데이터가 수정 안 되었다면 브라우저 캐시의 데이터를 또 사용하고 싶을 것이다.

 

서버에 star.jpg를 요청했고 응답헤더에 cache-control:max-age=60 값이 있어서 브라우저 캐시에 star.jpg가 저장되었다고 가정하자. 60초후 다시 star.jpg를 요청할 때, 요청데이터가 같기 때문에 브라우저 캐시에서 또 사용하고 싶다. 이 때 검증헤더조건부요청을 사용한다.

 

요청시 응답헤더에 last-modified:2022년 09월 01일 10:00:00 같은 값을 검증헤더라고 한다. 이 값을 브라우저 캐시에 같이 저장한다. 이후 60초가 지나서 다시 요청할 때 요청헤더에 if-modified-since: 2022년 09월 01일 10:00:00라는 조건부요청을 같이 보낸다. 서버에서 if-modified-since를 보고 값이 같으면(날짜 및 시간) Http Body를 제거하고 응답 헤더만 보낸다. 응답 헤더가 0.1M, Http Body가 1.0M라고 하면, 0.1M만 전송받기 때문에 속도가 빠를 것이다. 

 

응답헤더를 받고 브라우저 캐시의 헤더 데이터를 갱신하고 거기 있는 데이터를 사용하는 것이다.

 

서버에서 데이터가 변하지 않아서 응답헤더만 전송할 때 304 Not Modified로 날라온다.

 

우측에 last-modified, if-modified-since가 같은 것을 확인(304 Not Modified) - 출처 나무위키 이미지

 

 

이 방법은 유용하지만 Etag라는 방법도 있다.

 

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

 

Last-Modified의 단점은 다음과 같다.

 

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

 

위에서 설명한 Last-Modified 가 아닌 ETag(Entity Tag)라는 검증헤더를 사용하면 된다.

 

  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둔다 ex)ETag:"v1.0", ETag:"aaaa"
  • 데이터 변경시 이 이름을 바꾸어 변경함(Hash를 다시 생성) ex)ETag:"aaaa" -> ETag:"bbbb"
  • 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기

 

Etag를 사용할 때 조건부 요청 헤더는 If-Non-Match:Etag를 사용한다. 즉 요청시 브라우저 캐시의 데이터에 Etag가 있으면 아래와 같이 조건부 요청 헤더를 보낸다.

 

 

ETag를 사용하면 캐시제어로직을 서버에서 완전히 관리하고 클라이언트는 단순히 이 값을 서버에 제공한다.

 

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

 

Cache-Control(캐시제어)의 캐시 지시어는 다음과 같다.

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

 

Pragma는 Cache-Control이 나오기 전에 사용된 하위호환이다.(HTTP 1.0 하위호환)

 

Expires는 캐시 만료일 지정 하위호환이다. 지금은 Cache-Control:max-age를 권장한다. 그리고 Cache-Control:max-age와 함께 사용하면 Expires는 무시한다.

 

5.프록시 캐시

 

한국의 클라이언트가 미국의 원서버에 데이터 요청시 0.5초가 걸린다고 하자. 이 때 중간에 프록시 캐시 서버를 두면 프록시 캐시 서버와 미국의 원서버가 0.4초가 걸리고 한국의 클라이언트는 프록시 캐시에 요청하여 0.1초만에 데이터 응답을 받을 수 있다. 아래 그림과 같다.

 

 

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

 

6.캐시 무효화

 

  • Cache-Control : no-cache
    • 데이터는 캐시해도 되지만 항상 원(origin) 서버에 검증하고 사용
  • Cache-Control : no-store
    • 데이터에 민감한 정보가 있으므로 저장하면 안 됨
  • Cache-Control: must-revalidate
    • 캐시 만료 후 최초 조회시 원서버에 검증해야 함
    • 원서버 접근 실패시 반드시 오류 발생해야 함(504 Gateway Timeout)
    • must-revalidate는 캐시 유효 시간이라면 캐시를 사용함
  • Pragma: no-cache
    • HTTP 1.0 하위 호환

 

no-cache와 must-revalidate의 차이는 아래 그림을 참고하면 좋다.

 

no-cache는 원서버 단절되어도 캐시 데이터 반환 가능

 

must-revalidate는 원서버 단절시 504 에러

반응형