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

윤경·2021년 9월 3일
0

HTTP

목록 보기
8/8
post-thumbnail

[1] 캐시 기본 동작

캐시가 없다고 가정하고 별 이미지를 요청해보자. ⬆️ 총 무려 1.1M의 데이터를 전송해야 함 !!

그러고 또 똑같은 별 이미지를 요청했을 때 서버는 과연 얼마짜리 데이터를 전송하게 될까?

서버는 캐시가 없기때문에 또 !!!! 1.1M(헤더+바디)의 데이터를 또 !!! 전송하게된다.
캐시를 사용하지 않으면 이렇게나 불편하다.
분명 같은 데이터를 요청하는데도 계속 네트워크를 통해 데이터를 다운받아야 한다. (네트워크는 매우 느리고 비싸다 ..) 다운로드 받는 시간 때문에 브라우저 로딩 속도가 느려지고 우린 화가 난다.

이제 캐시를 적용한 예제를 살펴보자.

이로 인해 네트워크를 불필요하게 사용하지 않아도 되며 브라우저 로딩 속도를 높일 수 있다.
(우리 한 번 들어갔던 웹 브라우저는 굉장히 빨리 열리지 않는가. 그걸 생각해보자.)

🙋🏻‍♀️: 유효 시간이 지나고 같은 데이터를 요청하는 요청이 오면 어떡하지?

그냥 기존걸 지우고 다시 캐시를 덮어씌우면 된다. ➡️ 캐시 갱신 (이때 다시 네트워크 다운로드가 발생하긴 한다.)

🤷🏻: 차암나 근데 이거 좀 비효율적이지 않아? 그래봤자 같은 이미지면서 ~~!


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

캐시 유효 시간이 초과했을 때 경우는 두 가지.
서버에서 기존 데이터를 변경했거나 서버에서 기존 데이터를 변경하지 않았거나.

전자의 경우에는 당연히 데이터가 바뀌었으니 다시 다운로드 받는게 맞다고 생각하는데 후자는 .. 다시 다운 받기엔 너무 시간도 돈도 아까운데 ??

저장해두었던 캐시를 재사용할 순 없을까?

🤷🏻: 데이터가 바뀌지 않았다는 거, 증명할 수 있어? 내가 뭘 믿고 ??

클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요하다.

데이터가 마지막으로 수정된 시간을 적는 헤더를 사용하자.

데이터 최종 수정일이 서버와 클라이언트가 일치한다면 데이터가 같은 데이터인 걸 증명해주잖아 !!

즉,

캐시 유효 시간이 초과했다고 하더라도, 서버의 데이터가 갱신되지 않으면 304 Not Modified 응답과 함께 헤더 메타 정보만 날려 0.1M의 작은 데이터만 전송할 수 있다.

클라이언트는 캐시에 저장된 데이터를 재활용하여 결국 네트워크 다운로드가 발생한다고 해도 용량이 작은 헤더 정보만 다운로드해도 되므로 매우 실용적인 해결책이라고 할 수 있다.


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

검증 헤더

: 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
Last-Modified, ETag를 활용해 조건부 요청 헤더를 만들어 보냄

조건부 요청 헤더

검증 헤더로 조건에 따른 분기.

  • If-Modified-Since: Last-Modified 사용 (클라이언트가 서버에게 "이 이후 데이터가 수정 되었나요?")
  • If-None-Match: ETag 사용

조건 만족 = 200 OK
조건 만족 X = 304 Not Modified

If-Modified-Since, If-Modified-Since 단점

  • 1초 미만 단위로 캐시 조정 불가. 최소 초 단위

  • 날짜 기반 정해진 로직 사용. (날짜는 갱신 되었지만 컨텐츠 자체는 갱신되어있지 않을 수도 있음)
    즉, A → B → A 는 결과적으로 컨텐츠 변화가 없다. 하지만 날짜가 갱신되어 다시 다운 받아야 한다는 말.

  • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 (스페이스, 주석의 변화엔 관심 없어 !! 캐시 유지하고 싶어 !! ➡️ ETag 사용하자)

ETag, If-None-Match

: Entity Tag
캐시용 데이터에 임의의 고유한 버전 이름을 달아줌.
데이터가 변경되면 이름을 변경함. → Hash 다시 생성
ex. 헤더에 ETag="aaaa"를 같이 보내줌. 캐시에 이를 저장하고 이를 비교.

진짜 단순히 ETag만 보내서 같으면 유지, 다르면 다시 받는다는 것

캐시 제어 로직을 완전히 서버에서 관리. 클라이언트 입장에서는 완전 블랙박스가 되어버림.(전혀 모르는 일)


[4] 캐시와 조건부 요청 헤더

📌 캐시 제어 헤더와 관련된 헤더들

  • Cache-Control: ⭐️ 캐시 제어
  • Pragma: 캐시 제어(하위 호환)
  • Expireds: 캐시 유효 기간(하위 호환)

⭐️ Cache-Control

: 캐시 지시어(directives)

Cache-Control: max-age (얼마나 유효할거냐)

Cache-Control: no-cache
데이터는 캐시해도 되지만(가져다 써도 되지만) 항상 origin 서버에 검증하고 사용 !! (캐시 프록시 서버에는 뭘 하면 안되고 원서버까지 가서 검증해야 한다는 것

Cache-Control: no-store
데이터에 민감한 정보가 있어 저장하면 안 됨. 메모리에서 사용하고 최대한 빨리 삭제

Pragma

: 캐시 제어(하위 호환)

Pragma: no-cache 처럼 동작
HTTP 1.0 하위 호환

Expires

: 캐시 만료일 지정 (하위 호환)

캐시 만료일을 정확한 날짜로 지정 (지금 버전에서 사용하는 초 단위(Cache-Control: max-age)가 더 유연함)
HTTP 1.0부터 사용

검증 헤더, 조건부 요청 헤더

- 검증헤더 (Validator)
ETag: "v1.0", ETag: "asid93jkrh2l"
Last-Modified: Thu, 04 Jun 2020 07:19:24 GMT

- 조건부 요청 헤더
If-Match, If-None-Match: ETag값 사용
If-Modified-Since, If-Unmodified-Since: Last-Modofied값 사용


[5] 프록시 캐시

🤷🏻 프록시 서버는 뭐고 왜 필요할까 ??

그런데, 프록시 캐시 서버를 도입해보자. 이제 왜 프록시 캐시 서버가 필요한지 이해가 돼죠?

📌 Cache-Control
: 캐시 지시어(directives)

  • public
    : 응답이 public 캐시에 저장 가능
  • private (기본값)
    : 응답이 해당 사용자만을 위하기 때문에 private 캐시에 저장해야 함

⬇️ 이 둘은 이런게 있다~ 라고만 알아두자.

  • s-maxage
    : 프록시 서버에만 적용되는 max-age
  • Age: 60 (HTTP 헤더)
    : 오리진 서버에서 응답 후 프록시 캐시 내 머문 시간(초)

[6] 캐시 무효화

: "이 페이지는 진짜 캐시되면 안 돼 !!"

이렇게 캐시 무효화를 시키고 싶을 때는

  • Cache-Control: no-cache, no-store, must-revalidate
  • Pragma: no-cache
    를 모두 해주어야 한다.

하나하나씩 무엇을 의미하는지 살펴보자.

Cache-Control: no-cache

: 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용

(✔️ 아 그리고 :뒤에 오는 것들이 캐시 지시어다)

Cache-Control: no-store

: 데이터에 민감한 정보가 있으니 저장하지 말아라
(메모리에서 사용하고 최대한 빨리 삭제해라)

Cache-Control: must-revalidate

: 캐시 만료 후 최초 조회시 원 서버에 검증해야 함
원 서버 접근 실패시 반드시 오류가 발생해야 한다. → 504(Gateway Timeout)

Pragma: no-cache

: HTTP 1.0 하위 호환

🤷🏻 근데 이럴거면 must-revalidate 왜 써 ?? no-cache가 있는데 ??

no-cache

그런데 !! 순간 네트워크가 단절돼 원 서버에 접근 불가해지면 ?? ⬇️

must-revalidate


왜냐면 오늘 HTTP 진도가 다 끝났으니까요 ~~~ 헤헤

profile
개발 바보 이사 중

0개의 댓글

관련 채용 정보