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; # 캐시에 쓰지도 않는다
bypass 와 no_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 적중률 읽는 법을 참고하세요. 캐시 계층 설계와 검증을 포함한 서버 작업은 최적화 지원 사업이 담당합니다.