Skip to content

[5주차] RateLimit 수정 및 테스트 코드 작성#105

Merged
pyuseon merged 10 commits intohanghae-skillup:sliverzerofrom
sliverzero:week4
Feb 12, 2025
Merged

[5주차] RateLimit 수정 및 테스트 코드 작성#105
pyuseon merged 10 commits intohanghae-skillup:sliverzerofrom
sliverzero:week4

Conversation

@sliverzero
Copy link

제목(title)

[5주차] RateLimit 수정 및 테스트 코드 작성


작업 내용

이번 PR에서 진행된 주요 변경 사항을 기술해 주세요.
코드 구조, 핵심 로직 등에 대해 설명해 주시면 좋습니다. (이미지 첨부 가능)

  • RateLimit 수정
  • RateLimit 관련 테스트 코드 수정
  • 컨트롤러 테스트 코드 수정 및 작성

발생했던 문제와 해결 과정을 남겨 주세요.

ex) 문제 1 - 다수의 사용자가 동시에 같은 리소스를 업데이트할 때 재고 수량이 음수로 내려가는 데이터 불일치 문제 발생
해결 방법 1 - Redis SET 명령어에 NX(Not Exists)와 PX(Expire Time) 옵션을 활용해 락을 설정했습니다. 이유는 ~

이번 주차에서 고민되었던 지점이나, 어려웠던 점을 알려 주세요.

과제를 해결하며 특히 어려웠던 점이나 고민되었던 지점이 있다면 남겨주세요.

  • 아직 테스트 코드 작성이 익숙하지 않아 잘 작성했는지 모르겠습니다.

리뷰 포인트

리뷰어가 특히 의견을 주었으면 하는 부분이 있다면 작성해 주세요.

ex) Redis 락 설정 부분의 타임아웃 값이 적절한지 의견을 여쭙고 싶습니다.

  • 새로운 브랜치를 만들지 않고 기존 week4 브랜치에 커밋을 해서 5주차에 진행한 부분은 2월 9일 커밋 기록입니다.
  • RateLimit을 잘 수정했는지 궁금합니다.
  • 테스트 코드를 잘 작성했는지 궁금합니다.

기타 질문

추가로 질문하고 싶은 내용이 있다면 남겨주세요.

ex) 테스트 환경에서 동시성 테스트를 수행하였고, 모든 케이스를 통과했습니다. 추가할 테스트 시나리오가 있을까요?

  • 프로젝트를 도메인별 멀티 모듈 구조로 진행했습니다. 제 프로젝트가 MSA와 비슷하게 진행되고 있는지 도메인별 멀티 모듈 구조로 진행되고 있는지 궁금합니다.
    다른 분들처럼 계층별 멀티 모듈로 구조를 바꾸는 게 좋을까요?
  • 아직 벡엔드 쪽으로 깊게 다룬 프로젝트가 없어서 이 프로젝트를 포트폴리오의 메인 프로젝트로 사용하려고 합니다. 어느 부분을 더 보완했으면 좋겠다, 어떤 기술을 써보면 좋겠다, 어느 기능을 추가했으면 좋겠다 등 이후 진행 방향 추천해 주실 수 있을까요?

마지막까지 추가로 리뷰해 주셔서 감사합니다! 많이 부족하겠지만 열심히 배우겠습니다!


public RateLimitExceedException(String message) {
super(message);
this.httpStatus = HttpStatus.TOO_MANY_REQUESTS; // 429 상태 코드
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

429 상태코드를 적절히 설정해 주셨네요! 👍

Comment on lines +24 to +25
return new RateLimitResponseDto<>(429, "RATE_LIMIT_EXCEEDED", "요청 제한 횟수를 초과했습니다.", null);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요청 제한과 관련해서 적절한 response 코드를 사용해 주셨네요!
status 코드 외에도 custom 코드를 작성해 주셔서 클라이언트에서 파악하기 졸을 것 같습니다!

Comment on lines +22 to +24
private static final int REQUEST_LIMIT = 50;
private static final int BLOCK_HOURS = 1;
private static final int TIME_MINUTE = 60;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"조회 API 에 RateLimit 을 적용합니다. 비정상적 사용 패턴을 감지하고 시스템을 보호하기 위해 1분 내 50회 이상 요청 시 1시간 동안 해당 IP 를 차단합니다."
이 요구 사항에 맞춰 구현 하신 것 같은데요 TimeMinute는 1분을 고려 해서 선정하신 걸까요? 만약 60이 60초를 의미한다면 변수명을 수정하시는 것이 좋습니다!

Comment on lines +67 to +78
// 51번째 요청은 차단되어야 함
boolean finalResult = rateLimitInterceptor.preHandle(request, response, handlerMethod);
assertFalse(finalResult, "51번째 요청 차단 실패");

// 응답이 429 상태 코드인지 확인
verify(response).setStatus(HttpStatus.TOO_MANY_REQUESTS.value());

// 응답 본문을 JSON으로 변환하여 검증
responseWriter.flush(); // PrintWriter 내용을 보장
String jsonResponse = responseWriter.toString();
System.out.println("Response Body: " + jsonResponse); // 디버깅 메시지
RateLimitResponseDto<?> actualResponse = objectMapper.readValue(jsonResponse, RateLimitResponseDto.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요청 차단 부터 응답 코드까지 검증해 주셨네요! 훌륭합니다! 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 코드에는 동시에 요청이 왔을때 RateLimiter가 제대로 작동하는지에 대한 테스트코드가 없는데요.
이부분을 추가해주시면 더 서버가 더 견고해질거에요! 추가 하시는 것을 추천 드립니다!

}

@Test
void RateLimit_초과시_예약_차단() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rate Limiter가 동시 요청이 있을 시에도 잘 작동하는지와 관련된 테스트 코드를 하나 더 작성해보세요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 코드를 꼼꼼하게 작성해 주셨네요!
현재 validation 조건 별로 작성해 주신 것으로 보이는데요. 실제로 꼼꼼하게 validation이 작동하는지 확인하는것은 테스트 코드에서 중요한 부분입니다! 잘 작성해 주셨어요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이부분은 따로 주석처리하신 이유가 있으실까요?

Comment on lines +27 to +36
Theater theater1 = new Theater("Theater1");

screening = new Screening(movie1, theater1, LocalTime.now());

Users user1 = new Users("user1", 20);

reservation = new Reservation(user1, screening);

Seat seat1 = new Seat(theater1, "A", 1, reservation);
Seat seat2 = new Seat(theater1, "A", 2, reservation);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 데이터가 중복된다면 java-test-fixtures를 사용해보시는 것을 추천 드립니다.
테스트 데이터를 Fixture로 관리하고, 다른 모듈에서 이를 가져와 활용할 수 있어 중복 코드가 줄어듭니다!

Comment on lines +22 to +28
"local key = KEYS[1]\n" +
"local ttl = tonumber(redis.call('TTL', key))\n" +
"if ttl > 0 then\n" +
" return ttl\n" + // TTL이 남아 있으면 반환
"end\n" +
"redis.call('SET', key, 1, 'EX', 300)\n" + //TTL 설정 (5분)
"return 0";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lua Script 는 따로 파일로 관리하시는 것이 유지 보수 하기 편합니다!

@pyuseon
Copy link
Contributor

pyuseon commented Feb 10, 2025

5주차 까지 고생 많으셨습니다! 🙏

좋았던 점

  • 테스트 코드를 꼼꼼하게 작성해 주셨네요, domain, repository, service를 모두 작성해 주셔서 테스트 커버리지를 높히기 위해 노력하신게 느껴졌습니다!
  • Rate Limiter 구현시 Lua Script를 적용해 주셨어요!

아쉬운 점

  • 테스트 코드에서 중복이 발생하는 경우, java-test-fixtures를 활용해보는 것이 좋습니다. 다른 모듈에서도 동일한 테스트 데이터를 재사용할 수 있어 통합 테스트 시 관리가 편리해지고 중복 코드도 줄어듭니다.

리뷰 포인트

→ 코드 리뷰에 작성해 두었습니다.

기타 질문

프로젝트를 도메인별 멀티 모듈 구조로 진행했습니다. 제 프로젝트가 MSA와 비슷하게 진행되고 있는지, 도메인별 멀티 모듈 구조로 진행되고 있는지 궁금합니다. 다른 분들처럼 계층별 멀티 모듈 구조로 바꾸는 게 좋을까요?

  • 현재 구조도 괜찮습니다. MSA와 일부 유사한 부분이 있지만, 멀티 모듈 프로젝트의 특성을 고려하면 지금 방식도 적절한 설계라고 볼 수 있습니다.다만, 계층별 멀티 모듈 구조로 변경해보는 것도 좋은 경험이 될 수 있습니다. 이 경우 의존성 관리 방식이 어떻게 달라지는지 비교 분석해보시면 좋을것 같아요!

아직 백엔드 프로젝트를 깊이 있게 다룬 경험이 없어서 이 프로젝트를 포트폴리오의 메인 프로젝트로 사용하려고 합니다. 어느 부분을 더 보완하면 좋을까요? 어떤 기술을 적용해 보면 좋을까요? 추가하면 좋을 기능이 있을까요?

  • 동시성과 Rate Limiter 관련 테스트 코드가 작성되지 않은 것으로 보이는데요 이부분을 추가해 주시면 좀 더 완성도 높은 프로젝트가 될 것 같습니다. 메인 프로젝트로 사용하기 위해서는 Readme에 API명세와 기술 스택 멀티 모듈 구조에 대한 설명등을 조금 더 보강하면 좋을 것 같습니다. 성능테스트도 데이터를 좀 더 넣어서 추가로 해보시는 것도 좋아요! 테스트 시나리오를 작성해서요 !

주차별 과제 중 빠진 부분이 있다면 추가로 구현해 보시는 것을 추천드립니다. 그러면 프로젝트의 완성도가 한층 더 높아질 거에요!💡
지금까지 꾸준히 노력하며 과제를 끝까지 구현해 내신 점, 정말 대단합니다! 👏
이 경험이 앞으로 더 성장하는 발판이 될 거예요. 계속해서 도전하고 배우다 보면, 분명 좋은 결과가 따라올거에요!
그동안 고생 많으셨습니다. 🙇‍♀️

@pyuseon pyuseon merged commit 346bc80 into hanghae-skillup:sliverzero Feb 12, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants