Cloud Architect/Root Cause Analysis

Part 01. CloudFront 캐싱 정책 완벽 가이드

"Everything about infra" 2026. 1. 27. 01:51

 

안녕하세요!

이커머스 웹사이트 운영 중 겪은 AWS CloudFront 캐싱 정책

변경 장애 사례와 해결 방법을 정리해봤습니다.

 

 

 

01. HTTP 통신과 헤더의 이해

✅ 기본 HTTP 통신 흐름

 

간단하게, 고객이 웹사이트에 방문하게 된다면 아래와 같은 흐름으로 Traffic이 흘러갑니다.

[사용자 브라우저] → [CloudFront] → [Origin Server] → [CloudFront] → [사용자 브라우저]

 

첫번째 : 브라우저가 요청을 보냄

GET /index.php HTTP/1.1
Host: 이커머스 사이트 주소입니다.
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)
Accept: text/html
Accept-Language: ko-KR,ko;q=0.9
Cookie: PHPSESSID=abc123; user_id=456
Referer: https://google.com
  • Host : 어느 사이트에 접속하는지
  • User-Agent : 어떤 디바이스/브라우저인지 (모바일? 데스크톱?)
  • Accept : 어떤 형식의 응답을 원하는지
  • Accept-Language : 선호하는 언어
  • Cookie : 로그인 세션, 장바구니 등 사용자 정보
  • Referer : 어디서 왔는지 (사이트에 접근하기 이전 페이지)

 

두번째 : CloudFront가 요청 받음

CloudFront는 받은 요청을 보고 두 가지 결정을 한다.

아래와 같이 캐시 키를 사용하여 캐시 확인, 캐시가 있는지 없는지 요청을 받고 결정합니다.

 

1. 캐시 확인 (Cache key 사용)

Cache Key 생성:
  URL: /index.php
  + User-Agent: iPhone (설정된 경우)
  + Cookie: PHPSESSID=abc123 (설정된 경우)
  
예시 Cache Key: "index.php|iPhone|abc123"

2-1. 캐시 Hit

CloudFront: "아! 이거 캐시에 있네!" → 오리진 서버에 안 가고 → 바로 캐시된 응답 반환 → 빠름! 

2-2. 캐시 Miss

CloudFront: "캐시에 없네, 오리진 서버에 물어봐야겠다" → 오리진 서버로 요청 전달

 

세번째 : CloudFront → 오리진 서버 (Cache Miss 시)

Origin Request Policy에 따라 헤더 전달

GET /index.php HTTP/1.1
Host: origin-server.internal
User-Agent: Mozilla/5.0 (iPhone...)
Cookie: PHPSESSID=abc123 ←
Referer: https://google.com

이때 User-Agent, Cookie, Referer 헤더는 Origin Request Policy에 설정을 해야 전달되며,

설정을 안했을 시에는 헤더 전달이 안됩니다. 즉, 서버는 전달받은 헤더만 알 수 있습니다.

 

네번째 : 오리진 서버 응답

HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=300
Set-Cookie: session_token=xyz789

<!DOCTYPE html>
<html>
...모바일 버전 HTML...
</html>
  • 서버의 판단 과정 (PHP로 예시)
<?php
// User-Agent 헤더가 전달되었는지 확인
if (isset($_SERVER['HTTP_USER_AGENT'])) {
    $userAgent = $_SERVER['HTTP_USER_AGENT'];
    
    // 모바일 감지
    if (strpos($userAgent, 'iPhone') !== false || 
        strpos($userAgent, 'Android') !== false) {
        // 모바일 버전 HTML 반환
        include 'mobile_template.php';
    } else {
        // 데스크톱 버전 HTML 반환
        include 'desktop_template.php';
    }
} else {
    // User-Agent가 없으면 기본값 (데스크톱)
    include 'desktop_template.php'; // ← 문제 발생!
}
?>

 

다섯번째 : CloudFront가 응답 캐싱

1. Origin 응답 받음
2. Cache Key로 캐시에 저장
 - Key: "index.php|iPhone|abc123"
 - Value: Origin 응답 전체
3. TTL 설정 (Cache-Control 헤더 기반)
4. 사용자에게 응답 전달

 

여섯번째 : 다음 사용자 요청 시

다음 모바일 사용자:
   Cache Key: "index.php|iPhone|def456"
   → 쿠키 다름 → Cache Miss → 오리진 요청

똑같은 모바일 사용자:
   Cache Key: "index.php|iPhone|abc123"
   → 완전히 동일 → Cache Hit! → 바로 응답

 


1-1. User-Agent 헤더의 중요성

📌 User-Agent란? 브라우저가 자신의 신원을 알려주는 헤더

 

실제 User-Agent 예시

iPhone:
Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)
AppleWebKit/605.1.15 (KHTML, like Gecko)
Version/16.0 Mobile/15E148 Safari/604.1

Android:
Mozilla/5.0 (Linux; Android 13)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/112.0.0.0 Mobile Safari/537.36

Desktop Chrome:
Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/112.0.0.0 Safari/537.36

 

왜 User-Agent가 중요하냐면, 적응형 웹사이트에서는 같은 URL에서 디바이스별로 다른 URL을 제공합니다.

URL: https://example.com/

모바일 접속:
→ 모바일 최적화 레이아웃
→ 작은 이미지
→ 터치 친화적 버튼

데스크톱 접속:
→ 넓은 레이아웃
→ 큰 이미지
→ 마우스 호버 효과

 

그렇다면 만약, 서버가 User-Agent를 못받는다면?

<?php
// User-Agent 없음
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
    // 기본값으로 데스크톱 버전 반환
    include 'desktop_template.php';
}
?>

 

기본 값으로 데스크톱 버전을 반환하여 하기와 같은 결과를 초래한다.

  • 모바일 사용자는 데스크톱 버전을 받는다.
  • 그로 인해 레이아웃 깨짐.
  • 이미지 사이즈 안맞음.
  • 사용자 경험 최악 → 고객 재방문 X

1-2. Cookie 헤더의 역할

📌 Cookie란? 브라우저가 저장하는 작은 데이터 조각입니다.

 

Cookie 종류

  1. 세션 쿠키 (ex: PHPSESSID=abc123def456)
    • 로그인 상태 유지
    • 로그아웃 시 세션 쿠키 삭제됨.
  2. 영구 쿠키 (ex: user_pref=dark_mode)
    • 사용자 설정 저장
    • 브라우저 닫아도 유지
  3. 장바구니 쿠키 (ex: cart_id=789xyz)
    • 장바구니 내용 추적 가능.

 

만약, 쿠키가 전달되지 않으면 ?

<?php
session_start();

// 세션 쿠키가 없으면
if (!isset($_SESSION['user_id'])) {
    // 로그인 안 된 것으로 판단
    header('Location: /login.php');
    exit;
}

// 로그인된 사용자만 볼 수 있는 페이지
echo "환영합니다, " . $_SESSION['username'];
?>
  • 로그인했는데 로그인 안 된 것으로 인식 (고객 입장에서는 최악)
  • 관리자 역시 첫번째 이유와 같이 관리자 페이지에 접근 불가.
  • 장바구니 내용 사라짐 (추적 불가 → 고객 입장에서 쇼핑 불가)

02. CloudFront 동작 원리

상세 내용은 하기 링크를 참고합시다!

https://ssunghwan.tistory.com/17

 

[AWS CloudFront] AWS에서 CDN서비스 사용하기.

01. What is a CDN?CloudFront를 알아보기에 앞서, CDN이 무엇인지 알고 CF에 대해서 알아보도록 하자. 💁‍♂️ CDN 이란?Content Delivery Network라고 불리며, 전 세계에 분산된 서버 네트워크를 통해 콘텐츠를

ssunghwan.tistory.com

 

💁‍♂️ CloudFront가 없는 경우

단, 거리에 따라 지연 시간에 차이가 있으며, 아래를 참고해보자.

[사용자] ---> [웹 서버]
1ms                100ms

총 소요 시간: 101ms
문제: 멀리 있는 사용자는 느림
  • 서울 → 서울 서버 : 10ms
  • 부산 → 서울 서버 : 30ms
  • LA → 서울 서버 : 150ms
  • 런던 → 서울 서버 : 300ms

 

💁‍♂️ CloudFront가 있는 경우

[사용자] ---> [CloudFront 엣지] ---> [오리진 서버]
1ms                         20ms                       100ms

첫 요청: 121ms (약간 느림)
캐시 Hit 시: 21ms (5배 빠름!)

 

📌 Cache Key 역할 : 캐시를 구분하는 고유 식별자입니다.

  • Cache Key 구성 요소:
    • URL (필수)
    • Query String (선택)
    • Headers (선택)
    • Cookies (선택)

 

예시1) URL만 있을 경우 문제점 : 모바일 / 테스크톱 환경이 구분이 안된다.

Cache Key: "/index.php"

예시 2) URL + User-Agent 가 있을 경우 : 디바이스별 다른 캐시를 제공하므로, 환경 구분이 된다.

예시 2 (URL + User-Agent):
Cache Key: "/index.php|Mobile"
Cache Key: "/index.php|Desktop"

 

📌 실제 시나리오)

 

사용자 A (Mobile)

요청: GET /index.php
Cache Key: "/index.php|Mobile"
  • Cache Miss
  • 오리진에서 모바일 HTML 받음
  • 캐시 저장

사용자 B (Mobile)

요청: GET /index.php
Cache Key: "/index.php|Mobile" (동일!)
  • Cache Hit
  • 빠르게 응답. (Origin Server에 안가고, CoudFront 엣지에서 해결)

사용자 C (Desktop)

요청: GET /index.php
Cache Key: "/index.php|Desktop"
  • Cache Miss
  • 오리진에서 데스크톱 HTML 받음
  • 별도 캐시 저장

03. Cache Policy vs Origin Request Policy

두 가지 정책의 차이점에 대해 알아보도록 하자.

 

📌 Cache Policy (캐시 정책)

목적 : 캐시를 어떻게 구분할까?

Cache Policy:
  Headers:
    - CloudFront-Is-Mobile-Viewer
  Cookies:
    - PHPSESSID
  Query Strings:
    - All

이렇게 캐시 정책을 사용한다면, 같은 URL 이라도 모바일/데스크톱 다른 캐시, 로그인 사용자별 다른 캐시를 받는다.

 

즉, Cache Policy 영향은?

  • 캐시 Hit/Miss 결정
  • 캐시 효율성 결정
  • Origin에 Header 전달 안함.

 

📌 Origin Request Policy (오리진 요청 정책)

목적 : 오리진에 무엇을 전달할까?

Origin Request Policy:
  Headers:
    - User-Agent
    - Referer
  Cookies:
    - All
  Query Strings:
    - All

이렇게 오리진 요청 정책을 사용한다면 Cache Miss 시 오리진에 요청할 때 User-Agent 헤더, 쿠키를 전달하며

서버가 이 정보를 신뢰하고 판단이 가능하다.

 

즉, Origin Request Policy의 영향은?

  • 캐시 구분에 영향 없음.
  • 서버가 받는 정보 결정
  • 서버 응답 내용을 결정

3-1.  왜 둘다 필요할까?

시나리오 1) Cache Policy만 설정하였을 때

Cache Policy:
  Headers:
    - CloudFront-Is-Mobile-Viewer
    
Origin Request Policy:

 

사용자 (Mobile) 요청 동작 ex:

→ Cache Key: "/index.php|Mobile"
→ Cache Miss
→ 오리진 요청
→ User-Agent 헤더 없음
→ 서버가 데스크톱 버전 반환
→ 캐시 저장: "/index.php|Mobile" = 데스크톱 HTML

결과 : 모바일 캐시에 데스크톱 HTML이 저장되며, 모든 모바일 사용자가 데스크톱 버전을 받는다.

 

 시나리오 2) Origin Request Policy만 설정하였을 때

Cache Policy:
  URL: /index.php
    
Origin Request Policy:
  Headers:
    - User-Agent

 

사용자 별 요청 동작 ex:

사용자 A (모바일):
→ Cache Key: "/index.php" (디바이스 구분 없음)
→ Cache Miss
→ 오리진 요청 (User-Agent 전달)
→ 서버가 모바일 HTML 반환
→ 캐시 저장: "/index.php" = 모바일 HTML

사용자 B (데스크톱):
→ Cache Key: "/index.php" (동일!)
→ Cache Hit!
→ 모바일 HTML 반환

 

 시나리오 3) 둘 다 설정하였을 때

Cache Policy:
  Headers:
    - CloudFront-Is-Mobile-Viewer
    
Origin Request Policy:
  Headers:
    - User-Agent

 

사용자 별 요청 동작 ex:

사용자 A (모바일):
→ Cache Key: "/index.php|Mobile"
→ Cache Miss
→ 오리진 요청 (User-Agent 전달 ✓)
→ 서버가 모바일 HTML 반환
→ 캐시 저장: "/index.php|Mobile" = 모바일 HTML ✓

사용자 B (데스크톱):
→ Cache Key: "/index.php|Desktop" (다름!)
→ Cache Miss
→ 오리진 요청 (User-Agent 전달 ✓)
→ 서버가 데스크톱 HTML 반환
→ 캐시 저장: "/index.php|Desktop" = 데스크톱 HTML ✓

사용자 C (모바일):
→ Cache Key: "/index.php|Mobile"
→ Cache Hit! ✓
→ 모바일 HTML 반환 ✓