모든 개발자를 위한 HTTP 웹 기본 지식 : Cache

jkky98·2024년 7월 9일
0

HTTP

목록 보기
1/7

Cache 적용

클라이언트의 2번의 GET /star.jpg 요청에 대하여 캐시에 관련한 기술이 적용되어있지 않다면, 이는 HTTP 프로토콜에 의해 서버로 부터 2번 star.jpg가 넘어올 것이다. 만약 한 번의 통신에서 응답에 해당하는 용량이 1.1M(Http 헤더 : 0.1M, Http 본문(이미지) : 1M)이라면 총 응답에 2.2M의 용량을 응답에서 사용한다.

만약 캐시를 사용한다면, 첫번째 요청에 대한 응답으로 다음과 같은 HTTP 메시지가 작성될 수 있다.

HTTP/1.1 200 OK
Content-Type: image/jpeg
cache-control: max-age=60
Content-Length: 34012
lkj123kljoiasudlkjaweioluywlnfdo912u34ljko98udjklaslkjdfl;qkawj9;o4ruawsldkal;skdjfa;ow9ejkl3123123
  • cache-control: max-age=60 : 캐시 유효기간을 60s로 설정한다. cache-control 헤더에 의해 브라우저 캐시에 60s간 응답데이터가 존재하게 된다. 캐시가 60초 후 기간만료가 된다면 응답은 다시 60s에 해당하는 캐시정보와 함께 응답(1.1M)을 클라이언트측으로 송신한다.

이를 통해 두번째 요청에서는 캐시를 이용할 수 있다. 클라이언트는 동일한 요청을 서버에 보내고 서버는 동일한 요청을 확인하여, 클라이언트에 헤더 데이터만으로 응답한다. 위의 예시를 참고하면 응답데이터의 용량은 0.1M이 되고, 클라이언트는 캐시에서 데이터를 조회한다.

캐시 방식을 사용하지 않을 경우 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야한다. 이는 느린 사용자 경험을 일으킬 것이다. 반면 위와 같이 캐시를 효율적으로 잘 사용한다면 비싼 네트워크 사용량을 줄이고 빠른 사용자 경험까지 이끌어낼 수 있다.

검증 헤더

HTTP/1.1 200 OK
Content-Type: image/jpeg
cache-control: max-age=60
Last-Modified: 2020년 11월 10일 10:00:00
Content-Length: 34012
lkj123kljoiasudlkjaweioluywlnfdo912u34ljko98udjklasl
kjdfl;qkawj9;o4ruawsldkal;skdjfa;ow9ejkl3123123

cache-control외에 Last-Modified가 추가된다. 이는 같은 요청에 대한 서버의 데이터에 수정이 일어났는지에 대한 것이다. 그렇다면 브라우저 캐시에 저장되는 이미지 데이터는 max-age과 Last-Modified를 가진다.

60초 이전까지는 위의 작동방식과 그대로이다. 60초 동안 동일 요청시 캐시에서 가져오는 것이다. 만약 60초 이후(캐시 기간만료) 상황에서 Last-Modified가 고려된다. 만약 60초가 지났을 경우 캐시로부터 Last-Modfied 시간을 요청에 담는다. 서버에 보낸 Last-Modified와 서버에서 제공할 데이터의 Last-Modified가 같다면 다시 304로 하여금 캐시를 이용하도록 한다.(캐시 기간 다시 갱신)

GET /star.jpg
if-modified-since: 2020년 11월 10일 10:00:00

요청은 위와 같이 캐시의 데이터에 Last-Modified가 존재할 경우 요청 헤더에 if-modified-since에 해당 시간을 담아 서버로 보낸다.

즉 정리하면 캐시의 유효 시간을 초과해도 서버의 데이터가 갱신되지 않으면 304 Not Modified로 하여금 클라이언트가 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신하고, 클라이언트는 캐시의 데이터를 재활용한다.

ETag, If-None-Match

Etag란 캐시용 데이터에 임의의 고유한 버전 이름을 붙이는 것을 말한다. (Hash알고리즘 사용) 요청에 대한 응답 데이터의 해시 알고리즘에 의한 고유한 번호를 ETag헤더에 주입하여 클라이언트 측으로 응답한다.

브라우저 캐시에 ETag값과 함께 응답데이터가 저장된다. 클라이언트는 재요청에서 이 ETag를 함께 보낸다. 만약 리소스의 수정이 일어났다면 해시Func(리소스)시 요청에 들어온 ETag와 동일하지 않을 것이므로 그럴 경우 서버에서 응답데이터를 새로 구성해서 보내며 만약 같을 경우 304 -> 캐시처리가 이루어진다.

ETag를 이용하면 캐시 제어 로직을 서버에서 완전히 관리할 수 있다.
ETag를 사용하나 LastModified를 사용하나 계산은 서버에서 이루어지지 않나 싶지만 LastModified의 경우 서버가 아닌 곳에서 계산이 어떻게 이루어지는지 알 수 있다.(시간비교) 반면 ETag는 캐시 알고리즘을 서버에서 보유하고 있다.

캐시 제어 헤더

Cache-Control(캐시 지시어)

  • max-age(초 단위 - 캐시 유효시간)
  • no-cache(데이터는 캐시가능, 그러나 항상 원-서버에서 검증하고 사용할 것)
  • no-store(데이터에 민감한 정보가 있으므로 상태유지 하면 안된다.)
  • Pragma : no-cache(HTTP 1.0 하위 호환)
  • Expires : 캐시 만료일 직접 지정(하위 호환 - max-age 권장)

프록시 캐시

한국의 클라이언트가 미국의 원 서버까지 도달하는 시간은 꽤 걸리기 때문에 실제로 클라이언트는 한국 어딘가에 존재하는 프록시 캐시 서버를 이용하는 경우가 많다. 프록시 캐시 서버에는 public 캐시를 가지고 있으며 private 캐시의 경우에는 브라우저(개별 클라이언트)가 가지고 있다.

Cache-Control: public -> 프록시 캐시 서버로
Cache-Control: private -> 해당 사용자만을 위함(브라우저 캐시)
Cache-Control: s-maxage -> 프록시 캐시에만 적용되는 max-age

캐시 무효화

확실한 캐시 무효화를 위해서는 다음과 같이 응답메시지 헤더를 구성해야한다.

• Cache-Control: no-cache, no-store, must-revalidate
• Pragma: no-cache

no-cache로 하여금 항상 원 서버에 검증하도록 하고, no-store로 하여금 데이터를 캐시에 저장하지 않도록 한다. must-revalidate로 하여금 캐시 만료후 최초 조회시 원 서버에 검증하도록 해야하며 원 서버 접근 실패시 반드시 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개의 댓글