✨ 버그 설명
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.
✨ 원인
- 인프라 —
.env / .env.dev 의 REDIS_URL 이 가리키는 Upstash 호스트 unique-snail-97791.upstash.io 가 DNS NXDOMAIN (인스턴스 삭제/deprovision). 별도 조치 필요 (신규 인스턴스 프로비저닝 + URL 교체).
- 코드 —
src/config/redis.ts 는 createClient({ url }) 만 사용 → node-redis 는 연결 실패 시 명령을 오프라인 큐에 무한 대기. admin-visitor-stats.repository.ts 의 pfCount 는 그 상태에서 리턴이 안 오고, 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 은 신고된 엔드포인트만 즉시 복구.
✨ 개발 목록
✨ 기타
- Upstash 인스턴스 복구는 별개 작업. 복구 완료되면 이 PR 없이도 API 는 정상화되지만, 재발 방지 차원에서 코드 방어는 별도로 머지 필요.
- 방문자 카운트는 Redis 만 저장소이므로 인스턴스 잃으면 데이터 리셋. 백엔드 로직상 신규 카운트부터 다시 누적.
- 다른 Redis caller (settlement/payple, user-activity 등) 는 이번 스코프 아님. 필요 시 후속 이슈.
✨ 버그 설명
GET /api/admin/stats/visitors(dev/prod 공통) 이 502 Bad Gateway 로 응답. curl 로 직접 확인 시 서버가 응답을 안 주고 ELB idle timeout 에 걸림./api/admin/stats/members,/api/prompts등 Redis 를 안 쓰는 엔드포인트는 정상 200.redisClient.pfCount(...)에서 hang.✨ 원인
.env/.env.dev의REDIS_URL이 가리키는 Upstash 호스트unique-snail-97791.upstash.io가 DNS NXDOMAIN (인스턴스 삭제/deprovision). 별도 조치 필요 (신규 인스턴스 프로비저닝 + URL 교체).src/config/redis.ts는createClient({ url })만 사용 → node-redis 는 연결 실패 시 명령을 오프라인 큐에 무한 대기.admin-visitor-stats.repository.ts의pfCount는 그 상태에서 리턴이 안 오고, 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) 으로 나가고, 프론트가 페이지를 그릴 수 있게 함.✨ 개발 목록
src/config/redis.ts—connectTimeout: 3000,reconnectStrategy: retries => Math.min(retries * 200, 5000)src/stats/repositories/admin-visitor-stats.repository.ts— 3개 메서드에 타임아웃 폴백pnpm build확인✨ 기타