3장은 분량이 짧아 각자 읽어보는 것으로 하고, 4장으로 넘어갔다.

이번 장은 나의 slack VIP 그녀와 함께 발표를 맡았으며, 내가 맡은 범위는 1~2장이다.


처리율제한장치의 설계

처리율 제한 장치(rate limiter) 란?

처리율 제한 장치는 일정 시간 동안 허용되는 요청 수를 제한하여 서버 과부하와 악의적인 요청을 막는 장치이다.

HTTP를 예로 들면 이 장치는 특정 기간 내에 전송되는 클라이언트의 요청 횟수를 제한한다.
API 요청 횟수가 제한 장치에 정의된 임계치(threshold)를 넘어서면 추가로 도달한 모든 호출은 처리가 중단되는 것이다.

예시


최근 디스코드에 업로드 된 수상한 링크를 살펴보자.
체팅창을 도배하거나 선물하기 버튼을 빠르게 연타하면 일정시간 동작이 차단된다.
도배 금지 로직이 있는 것이다. 이것을 처리율 제한 장치라고한다.


...

  // 사용자의 동작이 시간당 메시지 허용횟수를 초과하면(=도배하면) 일정 시간 채팅을 차단

  if (state.messageCount > RATE_LIMIT_MAX) {

    state.blockedUntil = now + RATE_LIMIT_PENALTY_MS

    return RATE_LIMIT_PENALTY_MS

  }

...


이외에도 아래와 같은 기능을 처리율제한장치라고 한다.

  • 사용자는 초당 2회 이상 새 글을 올릴 수 없다.
    • 같은 IP 주소로는 하루에 10개 이상의 계정을 생성할 수 없다.
    • 같은 디바이스로는 주당 5회 이상 리워드(reward)를 요청 할 수 없다.

장점

1. 자원 고갈(Resource Starvation) 방지

DoS(Denial of Service) 공격으로 인해 과도한 요청이 서버 자원을 모두 소모하여 정상 사용자가 서비스를 이용하지 못하는 '자원 고갈(Resource Starvation)' 상황을 방지할 수 있다.

예시

구글 독스(Google docs) :API는 사용자당 분당 300회의 read 요청만 허용
x (sns): 3시간 동안 300개의 트윗만 올릴 수 있도록 제한

특정 허용 횟수를 초과한 요청은 서버가 처리를 중단하여 과도한 요청으로 서버가 과부하되는 것을 막는다.


2. 비용 절감

추가 요청에 대한 처리를 제한하면 불필요한 API 호출을 줄일 수 있다.
또한 서버를 과도하게 증설하지 않아도 되고, 중요한 API에 더 많은 자원을 할당할 수 있어 운영 비용을 절감할 수 있다.

예시

신용 조회, 신용카드 결제, 건강 정보 조회와 같이 호출 횟수에 따라 비용이 발생하는 API는 과도한 요청이 발생하면 비용이 빠르게 증가한다.

따라서 처리율 제한 장치를 적용하면 불필요하거나 비정상적인 요청을 차단하여 API 호출 비용을 절감하고, 중요한 요청에 자원을 우선적으로 사용할 수 있다.


3. 서버 과부하 방지

봇(Bot)의 대량 요청이나 사용자의 비정상적인 이용 패턴으로 발생하는 과도한 트래픽을 제한하여 서버 과부하를 방지할 수 있다.

예시

예를 들어 로그인 API에서 일정 시간 동안 허용되는 로그인 시도 횟수를 제한하면, 여러 비밀번호를 반복적으로 입력해 계정을 탈취하려는 비밀번호 대입 공격(Brute Force)과 봇의 반복 요청을 차단하여 서버 과부하를 예방할 수 있다.

추가로 CAPTCHA와 같이 요청을 보내는 주체가 사람인지 봇인지 판별하는 기능과 함께 사용하면 더욱 효과적으로 자동화된 봇의 접근을 방지할 수 있을 것이다.


1단계

문제 이해 및 설계 범위 확정
요구사항을 잘 정리하는 것이 중요하다.

처리율 제한 장치를 구현하는 데에는 여러 가지 알고리즘을 사용할 수 있으며, 각각 고유한 장단점을 가지고 있다. 대표적인 알고리즘은 다음과 같다.

알고리즘기능시간복잡도장점단점사용 예시
고정 윈도 카운터
(Fixed Window Counter)
일정한 시간 구간마다 요청 수를 세고 제한을 초과하면 차단O(1)구현이 간단하고 메모리 사용량이 적음경계에서 요청이 몰리면 실제 제한보다 많이 허용 가능채팅, 댓글, 로그인
이동 윈도 로그
(Sliding Window Log)
요청 시간을 모두 저장하고 최근 요청만 계산O(n)가장 정확함메모리 사용량이 많음인증 API, 관리자 API
이동 윈도 카운터
(Sliding Window Counter)
이전·현재 윈도 요청 수를 가중치로 계산O(1)정확도와 성능의 균형근사 계산이라 오차 가능금융·결제 API
토큰 버킷
(Token Bucket)
토큰을 일정 속도로 생성하고 요청 시 소비O(1)순간적인 요청(Burst) 허용토큰 설정이 중요API Gateway
누출 버킷
(Leaky Bucket)
일정한 속도로 요청 처리O(1)처리 속도가 일정요청이 대기하거나 버려질 수 있음스트리밍, QoS

각 알고리즘의 장단점을 비교하고 어떤 상황에서 해당 알고리즘을 선택할지 근거를 함께 설명하려면, 면접관과 원활한 소통을 통해 요구사항을 정리하자.


2단계

개략적 설계안 제시 및 동의 구하기

처리율장치의 위치, 알고리즘, 아키텍처를 고려하여 어떻게 구성할지 결정하는 단계

처리율장치의 위치

클라이언트-서버 통신모델 사용한다고 가정하자. 어디에 모델을 둘 것인가?

클라이언트 vs 서버 vs 미들웨어
기술 스택이나 엔지니어링 인력, 우선순위, 목표에 따라 선택지를 정해보자


클라이언트

" 불가능 "

클라이언트는 처리율 제한을 안정적으로 걸 수 있는 장소가 못 된다.
클라이언트 요청은 쉽게 위변조가 가능해서다. 모든 클라이언트의 구현을 통제하는 것도 어려울 수 있다.

(1) 클라이언트 요청은 쉽게 위변조가 가능하기에 처리율 제한을 안정적으로 걸 수 없다.
누군가 악의적으로 서비스를 공격하고자 할 때, 처리율장치의 코드를 제거하거나 우회해서 무제한 요청을 보낼 수도 있다.

(2) 지나치게 다양한 클라이언트의 종류
크롬, 사파리, 네이버 웨일 등 다양한 웹 브라우저와 iOS, Android 등 여러 플랫폼은 각각 지원하는 기능과 저장 방식이 다르기 때문에 모든 환경에서 동일한 처리율 제한 로직을 구현하고 유지·관리하기 어렵다.

예를 들어, 브라우저를 껏다켜도 데이터가 보존 되는 성질의 Local Storage에 처리율장치와 관련된 산출물을 저장한다고 하자.
브라우저에서는 Local Storage를 이용해 브라우저를 종료한 뒤에도 처리율 제한과 관련된 정보를 저장할 수 있다. 그러나 Android나 iOS 네이티브 앱에는 Local Storage가 없기 때문에 DataStore, SharedPreferences, UserDefaults 등 플랫폼별 저장소를 사용해야 한다.

이처럼 플랫폼마다 구현 방식이 달라 모든 클라이언트에서 동일한 처리율 제한 로직을 유지·관리하기 어렵다.


서버

서비스 특징에 맞는 알고리즘을 자유롭게 선택하고 싶다면, 처리율장치를 서버에 구현해야한다.

처리율장치를 서버에 구현하면 아래와 같은 방법으로 동작한다.

(1) 클라이언트가 HTTP 요청을 보낸다.
(2) 서버에 도착하면 가장 먼저 처리율 제한 장치가 요청을 검사한다.
(3) 제한을 넘지 않았으면 API 서버가 요청을 처리한다.
(4) 제한을 넘었다면 API 서버까지 가지 않고 요청을 차단한다.


미들웨어


알고리즘 선택에 제약이 있을 수 있지만, 중복 구현을 줄이고 모든 서비스에 동일한 정책을 일관되게 적용하고 싶다면 처리율 제한 장치를 미들웨어에 구현하는 것이 효과적이다.

이 방식은 처리율 제한 장치를 API 서버 내부에 두는 대신, 처리율 제한 미들웨어(Middleware)를 두어 API 서버로 전달되는 요청을 먼저 검사하고 통제한다.

클라우드 마이크로서비스의 경우 API Gateway라는 처리율 제한을 지원하는 미들웨어에 처리율제한장치를 위치시키는 경우가 많다. 클라우드 마이크로서비스는 기능별로 서버를 여러대 만들어 둔다는 특징이 있는데,

각 서버에 처리율 제한장치를 구현하는 것보다 모든 요청의 진입점인 API Gateway에서 한 번에 처리하는 것이 장치 관리와 확장 측면에서 훨씬 효율적이기 때문이다.


처리율장치를 위한 알고리즘

알고리즘의 개념과 장점 단점에 대해 상세히 다루고 있는 챕터이다.
위에서 표와 간략히 살펴봤으니 발표세션에서는 넘어가고 각자 읽어보는 것으로 하자..! ^^

처리율장치를 위한 아키텍처

처리율장치의 처리율제한은 어떻게 구현하는 것이 좋을까?
처리율 제한 알고리즘의 핵심은 '요청 횟수를 세는 것'임으로 효율적인 요청횟수 세기로 부터 이를 고민해 볼 수 있겠다.

개략적 아키텍처

처리율 제한의 기본 아이디어는 사용자, IP 주소, API 엔드포인트 등 추적 대상별로 카운터(Counter)를 두고, 설정한 한도를 초과하는 요청은 차단하는 것.

이때 카운터 저장소로는 디스크 I/O 병목이 발생하는 RDB 대신, 빠른 속도와 만료(TTL) 기능을 제공하는 인메모리 캐시(Redis 등)를 사용하는 것이 바람직하다.

구조 및 동작원리

주요 구성 요소

  • 클라이언트: API 요청을 전송한다.
  • 처리율 제한 미들웨어: API 서버 전단에서 요청을 중계하며 한도 초과 여부를 검사한다.
  • Redis (인메모리 저장소): 대상별 카운터와 만료 시간을 관리한다. (INCR, EXPIRE 명령어 활용)
  • API 서버: 제약을 통과한 요청을 받아 실제로 비즈니스 로직을 처리한다.

요청 처리 흐름

  • 요청 수신: 클라이언트가 보내는 HTTP 요청을 처리율 제한 미들웨어가 먼저 수신한다.
  • 카운터 조회: 미들웨어는 Redis의 지정 키(버킷)에서 현재 카운터를 가져와 설정된 한도와 비교한다.
  • 분기 처리:
    • 한도 초과 시: 요청을 즉시 거부(예: HTTP 429 Too Many Requests 반환)하고 API 서버로 전달하지 않는다.
    • 한도 내 요청 시: 카운터 값을 1 증가(INCR)시키고 만료 시간(EXPIRE)을 설정/갱신한 뒤, 요청을 실제 API 서버로 전달한다.

이렇듯, 1단계에서는 처리율 제한 장치의 정의와 핵심 필요성을, 2단계에서는 클라이언트/서버/미들웨어별 배치 위치와 Redis 기반 개략 아키텍처의 설계 방식을 알 수 있었다.

3단계에서는 상세 구현 및 분산 환경 고려사항을,
4단계에서는 심화 주제 및 클라이언트 대응 전략을 알아보자.


3단계

4단계

profile
양치기소녀

0개의 댓글