Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

봄디의 개발일지

[HTTP] 캐시 제어 헤더 (Cache-Control, Pragma, Expires, 프록시 캐시 서버) 본문

HTTP

[HTTP] 캐시 제어 헤더 (Cache-Control, Pragma, Expires, 프록시 캐시 서버)

bomdy 2024. 10. 20. 23:47

캐시와 관련된 헤더는 크게 3가지가 있습니다.

  • Cache-Control : 캐시 제어
  • Pragma : 캐시 제어 (하위 호환) - 거의 사용하지 않는다. 
  • Expires : 캐시 유효 기간 (하위 호환)

1️⃣ Cache-Control (⭐중요)

Pragma, Expires 는 하위 호환으로 Cache-Control 로 다 할 수 있습니다.

  • Cache-Control: max-age
  • Cache-Control: no-cache
  • Cache-Control: no-store

✅ Cache-Control: max-age

max-age 는 앞 포스팅에서도 설명한 것처럼 캐시의 유효시간을 설정하며, 초 단위로 입력할 수 있습니다. 

Cache-Control: max-age=60 이라고 하면 캐시의 유효시간은 60초를 의미합니다. 

 

✅ Cache-Control: no-cache

no-cache 는 데이터는 캐시해도 되지만, 항상 origin 서버에게 검증하고 사용하라는 의미입니다.

눈에 보이지는 않지만 origin 서버로 가기까지 중간에 proxy 서버 등등의 중간 서버들이 존재합니다. 

그 때 중간 서버에서 캐시하지 말고 origin 서버까지가서 검증을 해야한다는 것을 의미합니다. 

 

✅ Cache-Control: no-store

no-store 는 데이터에 민감한 정보가 있으므로 저장하면 안된다는 것을 의미합니다. 

원래 캐시를 하면 하드디스크에 저장이 되는데 no-store 로 올 경우 저장하면 안되고 메모리에서 사용하고 최대한 빨리 삭제해야함을 의미합니다. 


2️⃣ Pragma (캐시제어 - 하위호환)

Pragma: no-cache 라고 하면 위의 Cache-Control: no-cache 처럼 동작하는데 지금은 거의 사용하지 않습니다.


3️⃣ Expires (캐시 만료일 지정 - 하위 호환)

expires: Mon, 01 Jan 1990 00:00:00 GMT

 

expires 는 캐시 만료일을 정확한 날짜로 지정하는 것을 의미합니다. 

그러나, 지금은 더 유연한 Cache-Control: max-age 를 권장하고 있으며 

Cache-Control: max-age 와 함께 사용할 경우 expires 는 무시됩니다. 


4️⃣ 프록시 캐시

 

한국에 있는 클라이언트가 미국에 있는 origin 서버에 접근을 할 때, 500ms 가 걸린다고 가정하면 이미지 하나를 다운받는데 너무 오랜 시간이 걸립니다. (origin 서버란 애플리케이션에서 이미지를 제공하는 소스가 있는 서버를 의미합니다.)

 

따라서 도입하는 것이 바로 프록시 캐시 서버입니다. 

 

프록시 캐시 서버 도입

 

 

한국 어딘가에 프록시 캐시 서버를 두고 DNS 요청을 할 때 약간의 조작을 거쳐서 요청이 오면 미국에 있는 원 서버를 거치는 것이 아니라 프록시 캐시 서버를 거쳐서 오도록 합니다. 

 

따라서 웹 브라우저에서 요청을 하면 프록시 캐시 서버는 한국 어딘가에 있으므로 빠른 응답을 가능하게 합니다. 

최초로 요청을 할 때는 다운받는 시간이 걸릴 수 있어 느리지만, 두 번째 요청부터는 더 빠른 응답을 가능하게 합니다. 

 

  • Cache-Control: public 
  • 응답이 public 캐시에 저장되어도 된다는 것을 의미합니다. (중간에서 공용으로 사용하는 캐시 서버)
  • Cache-Control: private
  • 응답이 해당 사용자만을 위한 것이기에, private 캐시에 저장해야 합니다. (default 값)
  • 중간에 있는 프록시 캐시 서버에는 저장되면 안되는 것을 의미합니다. 
  • Cache-Control: s-maxage - 프록시 캐시에만 적용되는 max-age 입니다. 

5️⃣ 캐시 무효화

Cache-Control 을 통해 캐시를 무효화시킬 수 있습니다. 

 

캐시를 적용하지 않으면 캐시가 안되는 것이라고 생각할 수 있겠지만 캐시를 적용하지 않아도 웹 브라우저들이 GET 요청의 경우 임의로 캐시를 생성하게 됩니다. 

따라서 해당 페이지가 캐시 되지 않아야 한다면 모든 설정을 제대로 해야 합니다. 

 

확실하게 캐시를 무효화시키고 싶을 땐

 

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

Pragma: no-cache

 

이렇게 모든 설정을 해주셔야 합니다.

no-cache 와  no-store 는 위에서 설명했기 때문에 생략하겠습니다.

 

✅ Cache-Control: must-revalidate

  • 캐시 만료 후 최초 조회 시 origin 서버에서 검증해야 한다. 
  • origin 서버에 접근 실패 시 반드시 오류가 발생해야 한다. - 504 (Gateway Timeout)
  • must-revalidate 는 캐시 유효 시간이라면 캐시를 사용한다. 

✅ Pragma: no-cache

pragma: no-cache 는 HTTP 1.0 에서 요청 할 경우 Cache-Control: no-cache 를 인식하지 못하기 때문에 

하휘 호환성을 위해 작성해야 합니다. 

 

✅ Cache-Control: no-cache 의 기본 동작

Cache-Control: no-cache 기본 동작

 

웹 브라우저에서 요청을 보내면 프록시 캐시 서버에게 먼저 가고, no-cache 가 있으면 본인이 처리하면 안됨을 알고

원 서버에게 요청을 하고 원 서버가 검증을 해서 정상적으로 응답을 하는 것을 의미합니다. 

 

 

 

그러나, 만약 순간 프록시 캐시 서버에서 원 서버로의 네트워크가 단절이 되어 원 서버에 접근이 불가한 경우

오류를 보여주는 것보다는 오래된 데이터라도 보여주자 라는 의미에서 프록시 캐시가 데이터를 반환하여 응답을 합니다. 

이것이 no-cache 의 정책입니다. 

 

✅ Cache-Control: must-revalidate 의 기본 동작

Cache-Control: must-revalidate 의 기본 동작

 

 

no-cache 와는 다르게 must-revalidate 의 경우 프록시 캐시에서 원 서버로의 접근이 네트워크 단절로 불가한 경우

항상 오류가 발생해야 합니다. 

이 경우에는 504 Gateway Timeout 이 발생합니다.

 

예를 들어 돈과 관련된 정보의 경우 오류가 나면 보이지 않아야 하고 과거의 데이터가 프록시 캐시에 있으면 안되기 때문에 오류가 발생하지 않고 no-cache 처럼 동작한다면 통장 잔고가 예전의 것으로 보일 수 있는 문제 등이 발생할 수 있습니다.

 

이렇듯 캐시를 무효화 하려면 서버에서 HTTP 응답 코드를 만들 때 no-cache, no-store, must-revalidate 와 하위호환을 고려하여 Pragma: no-cache 까지 작성해주어야 합니다. 


 

🔍 참고글

인프런 김영한 강사님의  [모든 개발자를 위한 HTTP 웹 기본 지식] 섹션 9. HTTP 헤더2 - 캐시와 조건부 요청 강의를 참고하여 작성했습니다.