Technote

서버 · 인프라 심화

nginx FastCGI 페이지 캐시 우회 규칙 — 무엇을 캐시하면 안 되는가

페이지 캐시 도입에서 어려운 것은 켜는 것이 아니라 비켜 가야 할 요청을 빠짐없이 비켜 가는 것입니다. 우회 목록에서 하나가 빠지면 결제 웹훅이 캐시되는 사고가 납니다.

FastCGI 캐시는 비로그인 방문자의 완성된 HTML 을 nginx 가 직접 돌려주게 합니다 — PHP 를 아예 타지 않으니 효과는 극적입니다. 그래서 위험도 극적입니다. 캐시되면 안 되는 응답이 캐시되는 순간, 남의 화면이 남에게 나가거나 상태 변경이 증발합니다.

반드시 우회해야 하는 것들

  • POST 요청 전부 — 상태를 바꾸는 요청에 캐시된 응답을 주면 변경이 조용히 사라집니다.
  • 로그인 쿠키 보유자 — 로그인 사용자에게 비로그인 캐시를 주면 관리 바가 사라지고, 반대가 되면 남의 세션 화면이 나갑니다.
  • wp-admin · wp-login — 설명이 필요 없는 영역.
  • 결제 · 웹훅 REST 경로 — 외부 게이트웨이가 부르는 웹훅이 캐시되면 입금 확인이 갱신되지 않습니다. 장애가 “가끔, 두 번째 알림부터” 나기 때문에 추적이 지옥입니다.
  • 미리보기 · 장바구니류 동적 쿼리 — 파라미터로 사람마다 다른 화면.
set $skip_cache 0;

if ($request_method = POST) { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/wp-login.php|/wp-json/myshop/") { set $skip_cache 1; }
if ($http_cookie ~* "wordpress_logged_in|wp-postpass|woocommerce_cart") { set $skip_cache 1; }

fastcgi_cache_bypass $skip_cache;   # 캐시를 읽지 않는다
fastcgi_no_cache     $skip_cache;   # 캐시에 쓰지도 않는다

bypassno_cache항상 쌍입니다. bypass 만 걸면 그 요청의 응답이 캐시에 저장은 되어, 다음 비로그인 방문자가 로그인 화면 조각을 받을 수 있습니다.

캐시 키와 다국어 · 필터

기본 캐시 키는 URL 기반입니다. 그래서 화면을 가르는 상태는 전부 URL 에 있어야 합니다 — 언어 · 목록 필터를 쿠키에 두면 한 사람의 화면이 캐시에 저장돼 다른 사람에게 나갑니다. 쿠키로 상태를 관리하고 싶어질 때마다 이 문장을 떠올리면 됩니다: 캐시 키에 없는 상태는 존재하지 않는 상태다.

판정이 캐시보다 앞에 선다 — 순서가 곧 안전이다

검증

add_header X-Cache $upstream_cache_status;   # 검증 기간에만

# HIT / MISS / BYPASS 를 직접 확인
curl -sI https://example.com/ | grep X-Cache
curl -sI -X POST https://example.com/wp-json/myshop/webhook | grep X-Cache   # BYPASS 여야 한다

오브젝트 캐시 계층과의 역할 분리는 Redis 적중률 읽는 법을 참고하세요. 캐시 계층 설계와 검증을 포함한 서버 작업은 최적화 지원 사업이 담당합니다.

이 주제의 다른 글

노하우 목록으로

서버 · 인프라 실무

메일 발송, 직접 할 것인가 맡길 것인가

메일 서버를 직접 세우면 요금은 0원에 가깝습니다. 대신 도달률이라는 비용을 냅니다. 어느 쪽이 싼지는 문의 한 건의 가치로 계산됩니다.

창업가 3분 읽기

₩270,000 · 신청하기