[4주차] RateLimit 적용, 비관락/Redisson 분산락 적용#91
Merged
soonhankwon merged 8 commits intohanghae-skillup:somin-jeongfrom Feb 4, 2025
Merged
[4주차] RateLimit 적용, 비관락/Redisson 분산락 적용#91soonhankwon merged 8 commits intohanghae-skillup:somin-jeongfrom
soonhankwon merged 8 commits intohanghae-skillup:somin-jeongfrom
Conversation
|
안녕하세요 소민님 😃 |
soonhankwon
reviewed
Feb 4, 2025
| // IP 차단 여부 확인 | ||
| Long allowed = redisRateLimiterService.isAllowed(clientIp); | ||
| if (allowed == -1) { | ||
| throw new RateLimitExceededException(TOO_MANY_REQUEST_ERROR); |
There was a problem hiding this comment.
조회 API에 RateLimit 적용 및 429 응답을 주는점 좋습니다 👍
soonhankwon
reviewed
Feb 4, 2025
| @Slf4j | ||
| @Service | ||
| @AllArgsConstructor | ||
| public class RedisRateLimiterService { |
There was a problem hiding this comment.
Redis를 활용해서 rateLimit 요구사항 구현이 잘된점이 좋네요 👍
soonhankwon
reviewed
Feb 4, 2025
| } | ||
| // Redisson MultiLock 적용 (여러 개의 좌석을 동시에 보호) | ||
| redissonLockUtil.executeWithMultiLock(lockKeys, 5, 10, () -> { | ||
| saveReservationWithTransaction(reservationRequestDto, reservationSeats, screenRoomId); |
There was a problem hiding this comment.
락을 획득한 요청만 Transactional이 적용되도록 설계하신점 좋습니다 👍
다만, "스프링 특성"상 메서드에서 같은 클래스의 메서드를 호출할때 "애노테이션"이 적용되지 않습니다.
- 해당 문제일때 해결하는 방법을 찾아보시면 좋은 경험이 될 듯 합니다.
soonhankwon
reviewed
Feb 4, 2025
| throw new SeatException(ALREADY_RESERVED_SEAT_ERROR); | ||
| } | ||
| } | ||
| private void validateUserReserveSeats(List<SeatsDto> reservationSeats, Long userId, Long screenScheduleId) { |
There was a problem hiding this comment.
API 구현시 꼼꼼하게 Validation 진행하신 점이 인상깊습니다 👍
soonhankwon
reviewed
Feb 4, 2025
| @SpringBootTest | ||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
soonhankwon
reviewed
Feb 4, 2025
| } | ||
| } | ||
|
|
||
| public static void containsReservedSeat(List<SeatsDto> reservationSeats, List<SeatsDto> seatsDtoByUserId) { |
There was a problem hiding this comment.
현재의 반복문에서 stream을 사용하면 가독성을 향상시킬 수 있습니다 :)
soonhankwon
reviewed
Feb 4, 2025
| public static void validateContinuousSeats(List<SeatsDto> seats) { | ||
| seats.sort(Comparator.comparing(seat -> seat.getCol().getColumn())); | ||
|
|
||
| for (int i = 1; i < seats.size(); i++) { |
There was a problem hiding this comment.
반복문에서 리스트의 size()메서드를 반복호출하는것은 반복횟수가 많아질수록 성능에 좋지않습니다.
- 불필요한 습관은 굳이 사용하지 않는 편이 좋다고 생각합니다 :)
좋았던 점
아쉬웠던 점
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[4주차] RateLimit 적용, 비관락/Redisson 분산락 적용
작업 내용
비관락 구현
Seat 테이블에 좌석 데이터를 넣고, Seat 테이블에서 좌석을 조회할 때 락을 걸었습니다.
그리고 ReservationSeat과 Reservation 테이블에 예약 정보를 저장했습니다.
첫 번째 트랜잭션이 커밋된 후 락이 풀리면 그 다음 트랜잭션이 좌석에 대한 락을 얻게 되고, ReservationSeat 테이블에 좌석이 예약되어 있는지 조회할 때 락을 걸었습니다.
함수형 분산락 구현
Redisson MultiLock을 사용해서 모든 좌석의 락을 한꺼번에 획득해야 예약을 진행할 수 있도록 하였습니다.
MultiLock을 적용하기 위해 좌석 별로 락 키를 생성했습니다.
Guava RateLimiter
Guava RateLimiter를 사용해서 초당 2개의 요청만 허용하도록 구현했습니다.
Redisson RateLimiter
조회 API 에 Redisson RateLimit 을 적용하기 위해 1분 내 50회 이상 요청 시 1시간 동안 해당 IP 를 차단하는 Lua script를 작성해서 구현했습니다.
발생했던 문제와 해결 과정을 남겨 주세요.
이번 주차에서 고민되었던 지점이나, 어려웠던 점을 알려 주세요.
리뷰 포인트
기타 질문