SpringBoot

Springboot 속도 제한 및 조절 구현, 유량 제어 | Resilience4j

pepega 2025. 3. 17. 22:16

1. 적용 사유

2. Resilience4j가 뭔가요

3. 적용 방법

4. 결과

 

1. 적용 사유

https://roadmap.sh/projects/weather-api-wrapper-service

 

Weather API Project Idea

Build a weather API that fetches and returns weather data from a 3rd party API.

roadmap.sh

요 과제를 수행하다 Rate Limit을 조절해달라는 요구사항이 있어서 사용했습니다.

특정 API 의 요청이 일정 수치 이상 되면 오류 Response body를 반환합니다.

 

2. Resilience4j가 뭔가요

Resilience4j는 Circuit Breaker, Rate Limiter, Retry, Bulkhead사용하여

모든 함수형 인터페이스, 람다 표현식 또는 메서드 참조를 강화하는 고차 함수(데코레이터)를 제공합니다. 

 

요번 포스팅에선 Rate Limiter를 사용하기 때문에

Rate Limiter만 소개하겠습니다.

 

Rate Limiter

https://resilience4j.readme.io/docs/ratelimiter

 

1. Thread#1이 작업을 수행하며 permission을 가져옵니다.

2. permissions가 1이기 때문에 지속적으로 작업을 수행합니다.

3. Thread#2가 작업을 수행하며 permission을 가져옵니다.

4. permissions가 0이기 때문에 예약(reserve)을 걸어둡니다.

5. permissions의 cycle이 돌며 1이 된 경우 Thread#2가 깨어나 작업을 수행합니다.

 

쉽게 말해, Thread#1은 적절한 타이밍에 요청을 보내고 있어서 문제 없이 수행되고 있습니다.

반면, Thread#2은 허용 양을 초과하여 보냈음으로 잠시 대기 후 작업을 수행하게 됩니다.

이런 식으로 과부하를 방지하고 시스템이 안정적으로 작동되게 하는 것이 RateLimiter의 역할입니다.

 

3. 적용 방법

 

기본 설정 값입니다.

timeoutDuration: Thread가 permission을 얻을 때 까지 대기하는 시간입니다.

limitRefreshPeriod: permissions가 refresh 되는 주기

limitForPeriod: 한 번에 생성되는 요청 허용량

 

500ns마다 50개의 요청을 할 수 있고 50개의 요청이 넘어간 경우 최대 5초까지 대기할 수 있습니다.

초당 최대 요청 횟수를 계산하면 아래와 같습니다.

 

멋지지않나요?

 

실제 코드 적용 방법입니다.

 

Config

 

 

Controller

 

Config 설정은 아래와 같습니다.

20초 동안 5개의 요청만 허용합니다. 이를 초당 호출 건수로 계산하면

4초당 1번의 요청이 가능한 설정입니다.

Controller에 instances.weathers를 입력하면 적용 완료입니다.

 

 

4. 결과

 

부하를 주며 호출하게 될 경우 아래와 유사한 오류가 발생합니다.

 

적용 끝~ 요기까지

 

전체코드

https://github.com/GHGHGHKO/roadmap-weather

 

GitHub - GHGHGHKO/roadmap-weather

Contribute to GHGHGHKO/roadmap-weather development by creating an account on GitHub.

github.com

 

출처

https://resilience4j.readme.io/docs/ratelimiter