← 전체 글로 돌아가기

웹 개발

응답 캐싱이 가리는 버그 찾기

이전 응답이 캐시돼서 새 데이터를 못 볼 때 체계적으로 캐시를 제거하는 방법.

캐싱은 좋지만, 버그를 숨긴다. 응답이 캐시되면 실제 문제를 고쳐도 이전 응답을 계속 본다. 원인을 찾으려면 캐시 계층을 하나씩 확인해야 한다.

상태 코드부터

curl -i 'https://example.com/api/items?page=1'

상태 코드를 보면 캐시 여부가 보인다. 200 OK이지만 Cache-Control: max-age=3600이 있으면 캐시된 응답이다. ETag나 Last-Modified 헤더도 함께 보자.

요청 파라미터 확인

같은 URL이라도 파라미터가 다르면 캐시 키가 다르다. 만약 ?page=1?page=2가 같은 응답을 반환하면, 캐시 키 설정이 잘못된 것이다.

# 다른 파라미터로 여러 번 요청
curl 'https://example.com/api/items?page=1'
curl 'https://example.com/api/items?page=2'
curl 'https://example.com/api/items?page=1'  # 여전히 페이지 1인가?

캐시 제거 전략

로컬 개발에서는 브라우저 캐시를 비우거나, 개발자 도구에서 "캐시 비활성화" 옵션을 킨다. 배포 환경에서는 다르다.

브라우저 캐시

# 하드 리로드
# Ctrl+Shift+R (Windows/Linux) 또는 Cmd+Shift+R (Mac)

CDN/프록시 캐시

# 특정 URL의 캐시 제거 (Cloudflare 예시)
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {token}" \
  -d '{"files":["https://example.com/api/items"]}'

애플리케이션 캐시

Redis나 Memcached를 쓰면, 특정 키를 비운다:

redis-cli DEL "api:items:page:1"
redis-cli FLUSHDB  # 전체 비우기 (개발용)

응답 헤더로 캐싱 문제 판단하기

Cache-Control: no-cache, no-store  # 캐시 금지
Cache-Control: max-age=0  # 즉시 만료
Cache-Control: max-age=3600  # 1시간 캐시

민감한 데이터(사용자 정보, 실시간 데이터)는 no-cache를 붙인다. 자주 안 바뀌는 데이터(정적 리소스, 설정)는 max-age를 크게 설정한다.

인증 상태와의 상호작용

캐시된 응답이 인증 상태에 따라 달라질 수 있다. 로그인 전/후로 같은 URL을 요청했을 때 캐시된 응답(로그인 전)이 계속 나올 수 있다.

# 인증 헤더 포함
curl -H "Authorization: Bearer token" 'https://example.com/api/user'
curl -H "Authorization: Bearer other_token" 'https://example.com/api/user'

같은 응답이 나오면 캐시가 인증 상태를 구분하지 않는 것이다.

캐시 문제 확인 체크리스트

  1. 상태 코드와 Cache-Control 헤더 확인
  2. 요청 파라미터가 캐시 키에 포함되는지 확인
  3. 브라우저/CDN/애플리케이션 각 단계의 캐시 비우기
  4. 인증 상태별로 다른 응답을 받는지 확인
  5. 캐시 만료 시간이 합리적인지 재검토

캐시는 필요하지만, 문제를 숨길 수 있다. 버그를 빠르게 찾으려면 개발할 때는 캐시를 최소화하고, 배포 후에 캐시 전략을 다시 검토하는 게 좋다.