들어가기 전에
캐시의 생명 주기
웹 브라우저의 캐시 설정은 HTTP의 Cache-Control 헤더에 의해 이뤄집니다.
Cache-Control의 max-age를 통해 캐시의 유효 기간을 초 단위로 지정할 수 있습니다.
한 번 받아온 리소스의 유효 기간이 지나기 전이라면 브라우저는 서버에 요청을 보내지 않고
디스크 또는 메모리에서 캐싱된 값
을 읽어와 이를 활용합니다.
재검증
캐시의 유효 기간이 지났다고 캐싱한 값이 사라지는 건 아닙니다.
그렇기 때문에 브라우저는 조건부 요청으로 해당 캐시값이 유효한지
재검증을 시도합니다.
- 캐시값이 유효하다는 건 해당값에 변경이 없다는 의미입니다.
재검증 결과 브라우저의 캐시가 유효하다면 서버는 304 Not Modified
요청을 내려줍니다. 304 Not Modified응답은 HTTP 본문을 포함하지 않기 때문에 더 효율적입니다.
재검증 결과 캐시가 유효하지 않으면 서버는 200 OK
또는 적합한 상태 코드를 본문과 함께 내려줍니다.
재검증 요청 헤더
If-Modified-Since
와 Last-Modified
- 1초 미만 단위의 세세한 캐시 조정이 불가능합니다.
- 날짜 기반의 로직을 사용해야 합니다.
- 서버에서 별도의 캐시 로직을 활용할 수가 없습니다.
If-None-Match
와 ETag
- ETag란 변경을 확인하기 위해 캐시용 데이터에 붙인 임의의 변수입니다.
- 서버는 데이터가 변경됐다고 판단할 때 ETag값을 변경합니다.
클라이언트가 전달한 ETag와 서버의 ETag값이 동일하면 클라이언트는 해당 값을 그대로 사용합니다. 만약 ETag의 값이 다르다면 새로운 값을 받아가 대시 캐싱합니다.
- 캐시 제어 로직을 서버에서 완전히 관리할 수 있습니다.
no-cache와 no-store
- no-cache: 데이터 캐싱을 허용합니다. 다만 캐싱된 값을 사용할 때
항상 origin서버에 가져가 검증한 뒤 사용
하라는 의미입니다.
- max-age=0: no-cache는 컨텐츠 자체를 웹서버에서 받겠다는 의미, max-age=0은 캐싱된 컨텐츠의 유효성을 항상 검사받겠다는 의미지만 크게봤을 때 max-age와 no-cache는 차이가 거의 없습니다.
- no-store: 데이터 캐싱을 금지합니다.
- must-revalidate: 캐시가 만료됐을 경우 반드시 origin서버에서 검증해야 합니다. 만약 origin서버에 접근하지 못하면 반드시 오류(504 Gateway Timeout)를 반환해야 합니다.
- no-cache의 경우 origin서버에 접근하지 못할 경우 설정에 따라 중간 서버에서 캐싱한 정보를 이용할 수도 있습니다. 하지만 must-revalidate는 그러한 작업을 허용하지 않습니다.
캐시의 위치
사용자 브라우저뿐만 아니라 CDN과 같은 중간 서버에 값을 캐싱하고 이를 활용하는 것도 가능합니다.
CDN Invalidation: CDN에 저장되어 있는 캐시를 삭제하겠다는 의미입니다.
브라우저 캐시랑은 다른 것이기 때문에 CDN Invalidation을 했다고 해서 브라우저 캐시가 삭제되는 건 아닙니다.
중간 서버 캐시를 위한 설정
- cache-control: public/private
- public: 모든 사람과 중간 서버에 캐시를 저장할 수 있습니다.
- private: endUser의 브라우저에만 캐시를 저장할 수 있습니다.
- s-maxage
- 중간 서버에 저장되는 캐시의 만료기간을 별도로 설정하기 위한 옵션입니다.
토스에서의 Cache-Control
HTML
HTML리소스는 새로 배포가 이루어질 때마다 값이 바뀔 수 있기 때문에 항상 HTML 파일을 불러올 때 새로운 배포가 있는지 확인합니다.
이를 위해 Cache-Control값으로 max-age=0, s-maxage=31536000
을 설정했다고 합니다.
- 브라우저는 HTML파일을 가져올 때마다 서버에 재검증 요청을 보내고, 그 사이 배포가 있었다면 새로운 HTML파일을 내려받습니다. (max-age=0)
- CDN은 계속해서 HTML파일에 대한 캐시를 가지고 있도록 설정했습니다. 대신 배포가 이루어질 때마다 CDN Invalidation을 발생시켜 CDN이 서버로부터 새로운 HTML파일들을 받아오도록 설정했다고 합니다. (s-maxage=31536000)
JS, CSS 파일
JS와 CSS파일은 프론트엔드 웹 서비스를 빌드할 때마다 새로 생기기 때문에 URL 앞부분에 임의의 버전 번호를 붙여 빌드 결과물마다 고유한 URL을 가지도록
설정하고 있다고 합니다.
- 내용이 바뀌면 URL값이 바뀌기 때문에 같은 URL에 대해 내용이 변경되는 경우는 없습니다. 내용이 바뀔 여지가 없으므로 리소스의 캐시가 만료될 일도 없습니다.
- 그래서 Cache-Control값으로 max-age=31536000(최대치)를 사용하고 있다고 합니다. 이로써 새로운 배포가 일어나지 않는 한 브라우저는 캐시에 저장된 JS와 CSS를 계속 사용합니다.