서비스 운영 ·

캐시와 CDN이 빠른 화면과 오래된 화면을 함께 만드는 이유

먼저 답부터

캐시는 한 번 받은 응답의 복사본을 다시 쓰는 방식이고 CDN은 여러 지역의 가까운 서버에서 그 복사본을 전달하는 망입니다. 속도와 원본 서버 부담은 좋아지지만 보관 시간이 남아 있으면 옛 파일이 보일 수 있으므로 HTML의 재확인 규칙과 내용이 바뀔 때 파일 이름이 달라지는 자산 전략을 나눠야 합니다.

캐시와 CDN이 빠른 화면과 오래된 화면을 함께 만드는 이유 대표 이미지

웹사이트를 배포했는데 내 컴퓨터에는 새 화면이 보이고 다른 사람에게는 옛 화면이 보일 때가 있습니다. 파일을 제대로 올리지 못했을 수도 있지만 브라우저나 중간 서버가 이전 복사본을 아직 쓰는 상황도 있습니다. 원인을 모른 채 계속 재배포하면 확인할 버전만 늘어납니다.

캐시는 자주 찾는 상품을 동네 편의점에 미리 가져다 두는 것과 비슷합니다. 먼 창고까지 매번 갈 필요가 없어 빠르지만, 포장이 바뀌었는데 편의점에 옛 상품이 남아 있으면 새 제품과 헷갈립니다. 무엇을 얼마나 보관하고 언제 창고에 다시 물을지 규칙이 필요합니다.

캐시는 받은 응답의 복사본을 다시 쓰는 방식이다

cache는 이전에 받은 웹 응답을 잠시 저장했다가 같은 요청에 재사용하는 저장 공간 또는 동작입니다. 브라우저 안의 개인 캐시도 있고 여러 사용자가 함께 거치는 중간 캐시도 있습니다. 이미지, CSS, JavaScript처럼 자주 바뀌지 않는 파일은 다시 다운로드하지 않으면 화면이 빨리 열리고 데이터 사용량도 줄어듭니다.

캐시는 데이터베이스 캐시, 앱 내부 캐시 등 여러 뜻으로 쓰이지만 이 글에서는 HTTP 응답 캐시를 다룹니다. 주소, 요청 방식, 응답 헤더에 따라 같은 복사본을 쓸 수 있는지 판단합니다.

CDN은 가까운 지역에서 파일을 전달하는 서버망이다

CDN은 Content Delivery Network의 줄임말로 콘텐츠 전달망이라는 뜻입니다. 원본 서버에서 받은 파일을 여러 지역의 edge, 즉 사용자와 가까운 중간 서버에 보관해 전달합니다. 한국 사용자가 멀리 있는 원본 서버까지 매번 가지 않아도 되어 지연과 원본 부담을 줄일 수 있습니다.

CDN을 켰다고 모든 파일이 자동으로 같은 방식으로 저장되지는 않습니다. Cloudflare 공식 문서처럼 제품마다 기본 캐시 대상, 응답 상태, 쿠키와 헤더 처리 규칙이 다릅니다. 사용 중인 서비스의 현재 설정과 실제 응답 헤더를 확인해야 합니다.

Cache-Control은 복사본 사용 규칙을 설명한다

Cache-Control은 브라우저와 중간 캐시에 응답을 어떻게 다룰지 알려 주는 HTTP 헤더입니다. MDN은 no-cache가 저장 금지가 아니라 다시 사용하기 전에 원본에 재확인하라는 뜻이고, no-store는 저장하지 말라는 뜻이라고 구분합니다.

Cache-Control: no-cache
ETag: "page-v42"

이 예시에서 브라우저는 복사본이 있어도 서버에 현재 버전인지 물을 수 있습니다. 서버가 같은 버전이라고 답하면 본문 전체를 다시 받지 않고 사용할 수 있습니다. 로그인 뒤 개인화된 응답은 shared cache, 즉 여러 사용자가 공유하는 캐시에 섞이지 않도록 private 같은 지시와 서비스 설정을 함께 검토합니다.

HTML과 이름이 바뀌는 자산은 전략을 나눈다

HTML 문서는 어떤 JavaScript와 CSS 파일을 불러올지 알려 주는 시작점입니다. HTML을 너무 오래 고정하면 새 배포가 만든 파일 이름을 알지 못해 옛 화면이 이어질 수 있습니다. HTML은 재확인하게 하고, 내용이 바뀔 때 이름도 바뀌는 자산은 오래 보관하는 전략이 흔합니다.

index.html                → 자주 재확인
app-a81f3c.js             → 내용이 같으면 오래 보관
새 내용 app-b927de.js     → 새 이름이라 새로 받음

이름 뒤의 짧은 문자열은 내용에서 만든 hash, 즉 파일 버전을 구분하는 표식일 수 있습니다. 빌드 도구가 새 내용을 새 이름으로 만들면 CDN의 옛 파일을 급히 지우지 않아도 두 버전이 함께 존재할 수 있습니다.

오래된 화면은 층별로 확인한다

새로고침 한 번으로 해결되지 않으면 어디의 복사본인지 나눕니다. 브라우저 개발자 도구 Network 탭에서 문서와 자산의 주소, 상태, 응답 헤더를 봅니다. 시크릿 창이나 다른 네트워크 결과는 단서가 되지만 그것만으로 CDN 정상 여부를 확정하지 않습니다.

  • 공개 HTML이 새 자산 이름을 가리키는지 확인합니다.
  • 자산 URL이 200으로 열리고 내용이 새 빌드와 맞는지 봅니다.
  • Cache-Control, Age, ETag 같은 헤더를 기록합니다.
  • CDN의 캐시 적중 또는 우회 표시를 제품 문서와 비교합니다.
  • 로그인 사용자와 비로그인 사용자의 응답이 섞이지 않는지 확인합니다.
  • 실제 공개 주소를 브라우저와 원문 요청 두 방식으로 봅니다.

캐시 삭제는 대상과 영향을 알고 실행한다

purge는 CDN에 저장된 복사본을 지우는 동작입니다. 전체 삭제는 순간적으로 모든 요청을 원본 서버로 몰리게 할 수 있고, 잘못된 새 파일을 더 빠르게 퍼뜨릴 수도 있습니다. 가능한 경우 문제가 확인된 URL이나 태그처럼 좁은 범위부터 다룹니다.

브라우저 캐시를 지우라는 안내도 사용자의 로그인이나 오프라인 자료에 영향을 줄 수 있습니다. 먼저 새 파일 주소와 응답 헤더를 확인하고, 서비스 작업을 멈추지 않는 범위에서 재확인 방법을 안내합니다. 캐시 규칙을 모른 채 no-store를 모든 응답에 붙이면 속도와 뒤로 가기 경험을 잃을 수 있습니다.

오늘 바로 해볼 작은 실습

공개 사이트 한 곳의 응답을 읽기만 합니다.

  1. 브라우저 개발자 도구에서 Network 탭을 엽니다.
  2. 페이지를 새로고침하고 가장 위의 document 요청을 고릅니다.
  3. 응답 헤더에서 Cache-Control과 ETag를 찾습니다.
  4. JavaScript나 CSS 파일 하나의 이름을 적습니다.
  5. 다시 새로고침해 상태와 전송 크기가 달라지는지 봅니다.
  6. HTML과 자산에 같은 보관 규칙을 써야 할지 이유를 적습니다.

모르는 CDN purge나 배포 명령은 실행하지 마세요. 로그인 화면, 개인정보, 결제 결과를 공유 캐시에 저장하지 않고 캐시 키와 쿠키 처리 방식을 이해하지 못했다면 전체 캐시 규칙을 바꾸지 않습니다. 공개 문제를 고칠 때도 현재 헤더와 정확한 URL을 기록한 뒤 영향 범위를 좁혀야 안전합니다.

확인한 자료

함께 읽기

  • 오류와 로그를 진료 기록처럼 읽고 원인을 좁히는 순서

    디버깅은 오류 문장을 지우는 일이 아니라 같은 문제를 다시 만들 수 있는 조건을 기록하고 첫 실패 지점을 찾는 과정입니다. 화면 증상, 입력, 시간, 파일과 줄 번호, 기대 결과를 분리해 적은 뒤 한 번에 한 가지만 바꾸면 로그의 결과와 실제 원인을 혼동할 가능성이 줄어듭니다.

  • 저장과 빌드와 배포를 포장 배송 공개처럼 구분하기

    저장은 작업 파일을 남기는 일, 빌드는 소스 코드를 서비스용 결과물로 만드는 일, 배포는 그 결과물을 서버에 올리는 일입니다. 배포 성공 표시만으로 실제 공개 주소가 새 결과물을 제공한다고 단정할 수 없으므로 도메인, 번들, 핵심 기능과 메타데이터를 공개 환경에서 다시 확인해야 합니다.

  • GitHub Actions로 커밋마다 테스트가 도는 흐름 이해하기

    GitHub Actions의 CI는 push나 pull request 같은 사건이 생기면 별도 실행 컴퓨터인 러너에서 설치와 테스트 단계를 자동 수행하는 방식입니다. 워크플로 파일의 실행 조건, 권한, 비밀값 사용, 통과한 정확한 커밋을 확인해야 하며 초록 표시가 실제 배포나 모든 기능의 정상 동작까지 보장하지는 않습니다.