Skip to content

feat: Redis 기반 Rate Limit 공통 모듈 추가 - #111

Open
SinnoLn wants to merge 8 commits into
devfrom
feat/90-redis-ratelimit
Open

feat: Redis 기반 Rate Limit 공통 모듈 추가#111
SinnoLn wants to merge 8 commits into
devfrom
feat/90-redis-ratelimit

Conversation

@SinnoLn

@SinnoLn SinnoLn commented Jul 31, 2026

Copy link
Copy Markdown
Member

🔗 관련 이슈

Closes #90

📝 작업 내용

1. Rate Limit 공통 모듈 설계 및 구현

  • common/ratelimit 공통 인터페이스(RateLimiter) 및 관련 DTO/도메인 타입(RateLimitResult, RateLimitRule) 설계
  • Redis 기반 고정 윈도우 방식 구현체(RedisRateLimiter) 구현
  • 원자적 처리를 위해 Lua 스크립트 기반 INCRPEXPIRE 연산 적용
  • Redis 연결 실패/장애 발생 시 규칙별로 Fail-Open/Fail-Closed 전략을 선택할 수 있도록 구현, 관련 메트릭(rate_limit_fail_total) 수집 추가

2. AOP 및 Web MVC 설정

  • @RateLimited AOP 애노테이션 및 IP 기반 요청 차단을 위한 RateLimitInterceptor 구현
  • 프록시/로드밸런서 경유 환경을 고려해 X-Forwarded-For 헤더를 우선 참조하도록 IP 추출
  • RateLimitWebConfig를 통한 인터셉터 전역 등록 진행
  • app.rate-limit.rules.* 설정 클래스(RateLimitProperties) 추가
  • 애플리케이션 기동 시 애노테이션에 지정된 규칙 존재 여부를 검증하는 RateLimitRuleValidator 구현

3. 예외 및 에러 응답 처리

  • 한도 초과 시 던질 RateLimitExceededException 예외 클래스 추가
  • GlobalExceptionHandler 내 429 응답(HTTP status TOO_MANY_REQUESTS, 에러코드 C-005) 처리 구현
  • 초 단위로 올림 계산된 Retry-After 응답 헤더 추가 처리

4. 테스트 코드 작성 및 기존 슬라이스 테스트 보완

  • RedisRateLimiter, RateLimitInterceptor, RateLimitRuleValidator, GlobalExceptionHandler 단위/통합 테스트 작성
  • 전역 인터셉터 등록에 따른 기존 @WebMvcTest 슬라이스 테스트 Mocking 보완

✅ 체크리스트

  • 로컬에서 빌드 및 테스트가 통과했습니다.
  • 컨벤션(브랜치/커밋 메시지)을 준수했습니다.
  • 관련 문서를 수정했습니다. (필요한 경우)

💬 리뷰 참고 사항

  • 트래픽을 고려해 Redis의 ZSET을 이용한 Sliding Window Log나 Token Bucket 알고리즘이 아닌 Fixed Window 방식을 유지했습니다.
  • RateLimitWebConfig에서 인터셉터를 전역 등록함에 따라, Rate Limit 적용 여부와 관계없이 컨트롤러 슬라이스 테스트에 Mock bean이 추가되었습니다. 앞으로 컨트롤러 슬라이스 테스트 작성시 함께 추가 부탁합니다.
  • 가용성을 고려해 기본은 Fail-Open으로 두되, auth-login처럼 보안이 중요한 규칙은 fail-open: false 설정으로 Fail-Closed 처리하도록 규칙별로 선택 가능하게 만들었습니다.
  • 기본값(Fail-Open) 및 Fail-Closed 적용 대상 규칙 선정에 다른 의견 있으면 피드백 부탁합니다.
  • ⭐️마이그레이션은 후속 이슈로 분리했습니다. [CHORE] 기존 Rate Limit 구현체 신규 인터페이스로 마이그레이션 #110 에서 진행 예정입니다.

@SinnoLn SinnoLn self-assigned this Jul 31, 2026
@SinnoLn SinnoLn added the feat label Jul 31, 2026
@claude

claude Bot commented Jul 31, 2026

Copy link
Copy Markdown

PR 리뷰 요약 (자동 리뷰)

머지 전 반드시 확인이 필요한 항목만 정리했습니다.

🔴 Blocker

  1. 새 Rate Limit 모듈이 어떤 엔드포인트에도 적용되지 않음
    @RateLimited, RateLimitInterceptor, RedisRateLimiter, RateLimitWebConfig 등 이번 PR에서 추가한 공통 모듈 전체를 실제로 사용하는 @RateLimited(...) 애노테이션이 컨트롤러 어디에도 없습니다(테스트 코드 제외 grep으로 확인). application.yaml에도 app.rate-limit.rules 설정이 전혀 없습니다. 반면 /api/v1/auth/login/methods는 여전히 기존의 별도 구현체 auth/infrastructure/ratelimit/LoginMethodLookupLimiter(동일한 고정 윈도우 Lua 스크립트를 별도로 구현)를 그대로 사용하고 있습니다. 결과적으로 이번 PR은 실제로는 아무 데도 연결되지 않는 죽은 코드를 추가하면서, 기존에 이미 존재하던 사실상 동일한 로직과 중복까지 남기게 됩니다. Redis 기반 Rate Limit 공통 모듈 도입([FEAT] Rate Limit 공통 모듈화 (Redis) #90)이 실질적으로 완료되었다고 보기 어렵습니다. 최소 하나의 실제 엔드포인트(예: auth-login)에 적용하거나, PR 범위가 "인프라만"이라면 PR 설명/이슈에 후속 작업임을 명시해야 합니다.

  2. RateLimitIntegrationTest가 새로 추가한 코드를 전혀 검증하지 않음
    RateLimitIntegrationTest.loginMethodsLookup_exceedsLimit_returns429/api/v1/auth/login/methods에 31회 요청 후 429/AUTH-012를 검증하는데, 이는 위 1번과 같은 이유로 기존의 LoginMethodLookupLimiter/AuthErrorCode.LOGIN_METHOD_LOOKUP_COOLDOWN(AUTH-012) 때문에 통과하는 것이며, 이번 PR에서 추가한 RateLimitInterceptor/RedisRateLimiter/RateLimitExceededException(고정 에러코드 C-005)와는 무관합니다. 즉 이 PR의 신규 rate limit 인터셉터→리미터→예외 처리로 이어지는 전체 흐름을 실제 HTTP 요청으로 검증하는 테스트가 하나도 없습니다(RateLimitInterceptorTest, RedisRateLimiterTest는 각각 단위 테스트일 뿐 MockMvc를 통한 end-to-end 검증이 아님). 새 인터셉터/리미터 코드가 완전히 깨져도 이 테스트는 그대로 통과합니다. 테스트명/의도와 실제 검증 대상이 어긋나 있으므로, @RateLimited가 적용된 실제(또는 테스트용) 엔드포인트를 통해 C-005 응답을 검증하도록 고쳐야 합니다.

문제를 찾지 못한 나머지 항목(계층 아키텍처, JPA, 나머지 테스트 등)에 대해서는 별도로 지적하지 않았습니다.

Comment thread src/main/java/chaeso/zip/server/common/ratelimit/RateLimited.java
@SinnoLn
SinnoLn requested a review from 1117mg July 31, 2026 06:50
@SinnoLn SinnoLn linked an issue Jul 31, 2026 that may be closed by this pull request
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Rate Limit 공통 모듈화 (Redis)

1 participant