You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
처리율 제한이 필요한 이유는 '큰 트래픽을 감당하기 위해서'가 아니라,
어떤 기준을 가지고, 그것을 넘어가는 경우 요청을 거부하기 위해서이다.
e.g. IP 를 기준으로 한다면, 한 IP 에서 /reviews POST 요청이 1초에 20번 이상 오면 429 HttpStatus.TOO_MANY_REQUESTS 를 응답
1-2) 목표
사실 9월 30일에 누군가에 의한 리뷰 작성 폭탄이 있었다.
이런 상황이 다시 발생했을 때, 요청을 거부하는 것이 목표이다.
1-2) 처리율 제한 장치 위치
클라이언트 vs 미들웨어 vs 서버
클라이언트에 처리율 제한 장치를 두는 방법은 클라이언트의 구현 영역
미들웨어(e.g. API gateway, alb...)에 처리율 제한장치를 두는 것은 간편하고 구현이 쉬움
서버에 처리율 제한 장치를 두면, 자유롭게 알고리즘을 사용할 수 있지만, 추가 구현이 필요
2-1) aws 트래픽 필터링 서비스 - WAF (Web Application Firewall)
Layer 7의 Web Application에 대한 공격 탐지 및 차단
Nginx WAF 유료 모델을 이용하여 만든 서비스
사용 가능한 AWS services : CloudFront, ==Application LoadBalancer==, API Gateway, AWS AppSync
웹 트래픽 필터링 : IP 주소, HTTP 헤더 및 본문 또는 사용자 정의 URI와 같은 조건을 기준으로 웹 트래픽 필터링
TokenBucket은 버킷에 토큰을 가득 채운채로 시작, 토큰이 모두 고갈되면 일정 시간마다 충전해오는 방식
한번에 많은 요청이 오는 Bust 트래픽에도 유연하게 작동 가능하다.
LeakyBucket 은 버킷에 패킷을 채우고, 일정한 속도로 이를 처리하는 방식
트래픽이 얼마나 있든 상관없이 꾸준히, 동일한 양을 처리한다.
TokenBucket 은 버킷에 토큰이 없으면, Leaky Bucket은 버킷이 넘치면 TOO_MANY_REQUESTS 를 응답한다.
2-3) 자바 요청 처리 속도 제한 라이브러리 - Bucket4j vs RateLimiter
둘 다 자바 라이브러리로, 의존성을 추가해서 코드단에서 구현할 수 있다.
RateLimiter
Leaky Bicket 방식
빠르고 간편, 하지만 분산 서버에서 인스턴스별로 처리 속도가 일관되지 않을 수 있음
왜냐하면 어플리케이션에서 코드 차원으로 버킷을 관리하기 때문.
하지만 이론상으로는 일관되지 않은 처리 속도일 수 있지만,
ALB 가 거의 동일하게 트래픽을 분산해주기 때문에 큰 차이 없을 것으로 예상
Bucket4j
Token Bucket 방식
다양한 기능 지원, 상대적으로 러닝 커브 있음
외부 Redis 를 사용해서 인스턴스마다 동일한 속도 상태를 갖게 해서 일관된 처리량을 설정할 수 있음
하지만 외부 Redis와 통신해야하므로 네트워크 오버헤드가 생김
항목
RateLimiter (Guava)
Bucket4j
개요
Google Guava 라이브러리의 RateLimiter 클래스. 단순한 속도 제한 구현에 사용됨.
고급 속도 제한 라이브러리. 다양한 기능과 분산 환경 지원.
알고리즘
==Leaky Bucket (누출 버킷) 알고리즘==
==Token Bucket (토큰 버킷) 알고리즘==
사용의 편의성
==간단하고 직관적==인 API 제공. 빠르게 설정 가능.
다양한 기능으로 인해 약간의 ==학습 곡선==이 있음. 설정이 복잡할 수 있음.
기능
기본적인 속도 제한 제공. 고급 기능 부족.
고급 속도 제한 정책 구현 가능. 다중 대역폭, ==버스트 허용==, 리필 전략 등 지원.
분산 환경 지원
분산 환경 지원 없음. ==인스턴스별로 동작==
Redis 등 외부 스토리지와 통합하여 ==분산 환경에서 속도 제한 상태 공유 가능==
확장성
단일 인스턴스에서 사용에 적합. 확장성 제한적.
외부 스토리지를 통해 높은 확장성 제공. 많은 인스턴스에서도 효율적으로 작동.
성능
가볍고 빠름. ==추가적인 오버헤드 없음==
분산 환경에서 ==약간의 네트워크 오버헤드== 발생 가능. 성능 최적화 필요.
사용 사례
단순한 속도 제한이 필요한 단일 애플리케이션 인스턴스.
분산된 환경에서 복잡한 속도 제한 정책이 필요한 경우. API 게이트웨이, 마이크로서비스 등.
고급 기능
고급 기능 제한적. 커스텀 구현 필요.
다중 대역폭 제한, 동기/비동기 API, 분산 잠금 등 다양한 고급 기능 제공.
의존성 및 종속성
Guava 라이브러리에 포함됨. 추가 종속성 거의 없음.
외부 스토리지 사용 시 추가 종속성 필요 (예: Redis 클라이언트 라이브러리).
예시 코드의 복잡도
==간단한 코드==로 구현 가능.
설정과 통합이 복잡할 수 있음. ==코드량이 많아질 수 있음==
2-4) 식별자 생성, Redis에 저장하는 방식
각 요청에 대해 고유 식별자를 생성하거나, (e.g. 요청 Dto의 해시코드)
또는 사용자가 접속했을 때 세션을 발급해서 사용자를 식별해서
이를 키로 활용해서 Redis 에 저장하는 방식
만약 Redis 에 이미 해당키가 존재한다면, 중복된 요청으로 간주해서 예외를 응답할 수 있다.
그리고 식별자를 저장할 때, 만료 기간을 지정함으로써 메모리를 최적화해야 한다.
➡️ 아무래도 우리가 분산 환경이다보니 레디스를 외부에 둘테니까.. 네트워크 부하가 나올 수 있을 것 같긴 하다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
1-1) 왜 필요한가?
처리율 제한이 필요한 이유는 '큰 트래픽을 감당하기 위해서'가 아니라,
어떤 기준을 가지고, 그것을 넘어가는 경우 요청을 거부하기 위해서이다.
e.g. IP 를 기준으로 한다면, 한 IP 에서 /reviews POST 요청이 1초에 20번 이상 오면 429
HttpStatus.TOO_MANY_REQUESTS
를 응답1-2) 목표
사실 9월 30일에 누군가에 의한 리뷰 작성 폭탄이 있었다.
이런 상황이 다시 발생했을 때, 요청을 거부하는 것이 목표이다.
1-2) 처리율 제한 장치 위치
클라이언트 vs 미들웨어 vs 서버
2-1) aws 트래픽 필터링 서비스 - WAF (Web Application Firewall)
Layer 7의 Web Application에 대한 공격 탐지 및 차단
Nginx WAF 유료 모델을 이용하여 만든 서비스
사용 가능한 AWS services : CloudFront, ==Application LoadBalancer==, API Gateway, AWS AppSync
웹 트래픽 필터링 : IP 주소, HTTP 헤더 및 본문 또는 사용자 정의 URI와 같은 조건을 기준으로 웹 트래픽 필터링
Web ACL 1개당 : $ 5/Month
Rule 1개당 : $ 1/Month
요청 1백만 건당 : $ 0.6
2-2) 자바 요청 처리 속도 제한 알고리즘 - Token Bucket vs Leaky Bucket
ref. https://velog.io/@cjy1705/RateLmiter-Rate-Limiter와-알고리즘
ref. https://medium.com/@apurvaagrawal_95485/token-bucket-vs-leaky-bucket-1c25b388436c
TokenBucket은 버킷에 토큰을 가득 채운채로 시작, 토큰이 모두 고갈되면 일정 시간마다 충전해오는 방식
한번에 많은 요청이 오는 Bust 트래픽에도 유연하게 작동 가능하다.
LeakyBucket 은 버킷에 패킷을 채우고, 일정한 속도로 이를 처리하는 방식
트래픽이 얼마나 있든 상관없이 꾸준히, 동일한 양을 처리한다.
TokenBucket 은 버킷에 토큰이 없으면, Leaky Bucket은 버킷이 넘치면 TOO_MANY_REQUESTS 를 응답한다.
2-3) 자바 요청 처리 속도 제한 라이브러리 - Bucket4j vs RateLimiter
둘 다 자바 라이브러리로, 의존성을 추가해서 코드단에서 구현할 수 있다.
RateLimiter
Leaky Bicket 방식
빠르고 간편, 하지만 분산 서버에서 인스턴스별로 처리 속도가 일관되지 않을 수 있음
왜냐하면 어플리케이션에서 코드 차원으로 버킷을 관리하기 때문.
하지만 이론상으로는 일관되지 않은 처리 속도일 수 있지만,
ALB 가 거의 동일하게 트래픽을 분산해주기 때문에 큰 차이 없을 것으로 예상
Bucket4j
Token Bucket 방식
다양한 기능 지원, 상대적으로 러닝 커브 있음
외부 Redis 를 사용해서 인스턴스마다 동일한 속도 상태를 갖게 해서 일관된 처리량을 설정할 수 있음
하지만 외부 Redis와 통신해야하므로 네트워크 오버헤드가 생김
2-4) 식별자 생성, Redis에 저장하는 방식
각 요청에 대해 고유 식별자를 생성하거나, (e.g. 요청 Dto의 해시코드)
또는 사용자가 접속했을 때 세션을 발급해서 사용자를 식별해서
이를 키로 활용해서 Redis 에 저장하는 방식
만약 Redis 에 이미 해당키가 존재한다면, 중복된 요청으로 간주해서 예외를 응답할 수 있다.
그리고 식별자를 저장할 때, 만료 기간을 지정함으로써 메모리를 최적화해야 한다.
➡️ 아무래도 우리가 분산 환경이다보니 레디스를 외부에 둘테니까.. 네트워크 부하가 나올 수 있을 것 같긴 하다.
Beta Was this translation helpful? Give feedback.
All reactions