Skip to content

[FIX] Redis 장애 시 admin 방문자 통계 API 가 502 로 hang — visitor stats 그레이스풀 폴백 #524

Description

@minij02

✨ 버그 설명

GET /api/admin/stats/visitors (dev/prod 공통) 이 502 Bad Gateway 로 응답. curl 로 직접 확인 시 서버가 응답을 안 주고 ELB idle timeout 에 걸림.

  • /api/admin/stats/members, /api/prompts 등 Redis 를 안 쓰는 엔드포인트는 정상 200.
  • 문제 엔드포인트 3개는 모두 첫 redisClient.pfCount(...) 에서 hang.

✨ 원인

  1. 인프라.env / .env.devREDIS_URL 이 가리키는 Upstash 호스트 unique-snail-97791.upstash.ioDNS NXDOMAIN (인스턴스 삭제/deprovision). 별도 조치 필요 (신규 인스턴스 프로비저닝 + URL 교체).
  2. 코드src/config/redis.tscreateClient({ url }) 만 사용 → node-redis 는 연결 실패 시 명령을 오프라인 큐에 무한 대기. admin-visitor-stats.repository.tspfCount 는 그 상태에서 리턴이 안 오고, Express 요청이 그대로 소켓을 잡고 있어 ELB timeout → 502.

즉 Upstash 를 복구해도 재발 방지가 없으면 다음 장애 때 같은 증상.

✨ 해결 방향

  • src/config/redis.ts: socket.connectTimeout + 상한 있는 reconnectStrategy 추가.
  • src/stats/repositories/admin-visitor-stats.repository.ts: 각 pfCount 를 짧은 타임아웃 + 폴백 0 으로 감싸 그레이스풀 저하. Redis 죽어도 응답은 200 (카운트 0) 으로 나가고, 프론트가 페이지를 그릴 수 있게 함.

disableOfflineQueue 를 전역으로 켜지 않는 이유: settlement 캐시/락 등 다른 caller 들이 await redisClient.set/get 를 하고 있어 갑작스런 throw 는 별도 이슈. 이번 PR 은 신고된 엔드포인트만 즉시 복구.

✨ 개발 목록

  • src/config/redis.tsconnectTimeout: 3000, reconnectStrategy: retries => Math.min(retries * 200, 5000)
  • src/stats/repositories/admin-visitor-stats.repository.ts — 3개 메서드에 타임아웃 폴백
  • pnpm build 확인

✨ 기타

  • Upstash 인스턴스 복구는 별개 작업. 복구 완료되면 이 PR 없이도 API 는 정상화되지만, 재발 방지 차원에서 코드 방어는 별도로 머지 필요.
  • 방문자 카운트는 Redis 만 저장소이므로 인스턴스 잃으면 데이터 리셋. 백엔드 로직상 신규 카운트부터 다시 누적.
  • 다른 Redis caller (settlement/payple, user-activity 등) 는 이번 스코프 아님. 필요 시 후속 이슈.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixfixing codes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions