우리는 요청수를 제한하기위해 RateLimiter을 사용한다.
주로 많이 사용하는 라이브러리로는 Resilience4j인데,
사용법은 결국 초당 몇건(TPS)가 넘으면 요청을 막을래!로 설정을 셋팅하여 사용 한다.
해당 max tps를 설정하기위해서는 성능테스트를 거쳐, 값을 측정하고, 예측에 의한 정적인 max tps를 설정하게 된다.
물론 이 정도의 기능도 상당히 프로덕션 서비스에서는 많이 유용하지만,
그 측정값이라는것이 정확하지 못하고, 여러 노드로 이뤄지거나, 환경이 다르거나에 따라 갭이 상당할수도있다.
이런 경우,
프로덕션 환경에서는 시스템에 부하를 줄정도로 더 요청을 받거나,
또는 시스템을 100% 사용하지 못하는 선에서 요청을 거부하게 RateLimiter가 동작하기도 한다.
이런 부분을 어떻게 잘 설정을 할수있을까? 라는걸 생각해 봤다.
정적인 값으로 설정하는게 아닌,
실제 데이터를 바탕으로 실시간으로 RateLimiter의 max tps를 구하여 적용하는 방법으로 구현을 할수도있지 않을까?
라는 생각을 했다.
우선 시스템의 CPU 로드와 Memory 사용량, 요청 TPS등을 쉽게 구할수있는 Actuator를 사용해서 서버의 지표데이터를 수집한다.
내가 구현하려는 RateLimiter에서는 주기적으로 해당 지표를 모니터링하면서,
실제로 Cpu로드나 Memory가 정해진 측정치까지 도달하는지, 여유가 있는지 여부를 실시간으로 계산한다.
이에 따라,
요청을 더받고, 덜받고를 실시간으로 판단하도록 만들면, 시스템의 성능을 최대한 사용할수있는 RateLimiter가 나오지 않을까 한다.
조만간 능동형 RateLimiter를 직접 만들어볼 생각이다.
1) 시스템 정보 수집 : Actuator
2) 실시간 로그 측정 및 지표 계산 : esper (cep)
3) RateLimiter : Resilience4j를 감싸서 커스터마이징하거나, 여의치않다면, 직접 Aop로 구현을 할생각.
4) 어드민 : 최대 성능을 쉽게 설정하고 모니터링하는 어드민 페이지.
위 4개의 스탭으로 플랜을 세웠다.
이건 LMax Distruptor's RingBuffer의 개념에서 영감이 떠올랐다.
RingBuffer를 사용하는 여러 이유가 있지만, 시스템의 성능을 최대로 사용하기 위함이 있다는 내용을 읽은적이있다.
Distruptor에서는 링버퍼를 시스템이 여유가있다면, 좀더 많은 일을 시키고 (링버퍼내의 이벤트를 빠르게 소진),
시스템이 여유가 없는 부하상태라면, 일을 대기하거나 조금씩 시키도록 하는데(링버퍼내의 이벤트를 적게 소진), 링버퍼를 활용한다.
RateLimiter도 정적인 값을 미리 설정하고 그값에 의해서 동작하는것보다는
좀더 실시간으로 시스템의 로드를 파악하고 인지한 상태로 좀더 요청을 처리할수있는 상태라면 좀더 요청을 받도록 동작하고,
그 반대라면 요청을 줄여주는 능동형으로 동작하면 더 좋겠다는 생각에서 이런 고민을 하게되었다.
이름은...뭐라고 할까?.. (ReactRateLimiter 정도?! ㅎㅎ)
'MY아이디어' 카테고리의 다른 글
| [아이디어] 코틀린의 Delegate를 이용한 ReadableMap 구현에 대해서 (0) | 2026.01.12 |
|---|
