> For the complete documentation index, see [llms.txt](https://real-dev.gitbook.io/real-library/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://real-dev.gitbook.io/real-library/learn_large_scale_system_design_fundamentals_with_virtual_interview_examples/readme/chapter4..md).

# Chapter4. 처리율 제한 장치의 설계

### 개요 &#x20;

* 처리율 제한 장치란 일정 시간 동안 요청 횟수 기준을 초과하는 요청을 무시하거나, 일정 시간 이후 처리하도록 핸들링하는 객체를 의미한다. &#x20;
* 클라이언트에 있을 수도 있고, 서버에 있을 수도 있지만 클라이언트 요청은 지나치게 조작이 쉬우므로 적합하지 않아 서버 혹은 클라이언트와 서버 사이의 미들웨어에서 처리하는 것이 일반적이다.
* 처리율 제한 장치는 요구사항에 따라 까다롭지만 `공격에 의한 자원 고갈 공격 방지, 비용 절감, 서버 과부하 방지` 등의 장점을 갖는다.

***

### 문제 해결 절차

#### 1. 문제 이해 및 설계 범위 확정

* 이 단계에서

  * 어떤 종류의 처리율 제한 장치여야 하는지
  * 규모는 어느 정도를 염두에 두는지
  * 시스템이 단일 서버 환경을 기준으로 동작하는지 혹은 분산 환경을 기준으로 동작하는지
  * 어떤 기준을 통해 처리율을 제한할 것인지

  등 설계 범위 및 동작 방식을 확정한다.

<figure><img src="/files/QFCcJz8ChYvksKy4WZrK" alt=""><figcaption><p>면접관과 질의응답을 통해 도출된 요구사항</p></figcaption></figure>

***

#### 2. 개략적인 설계안 제시 및 컨펌

* 클라이언트와 서버 사이의 미들웨어에서 처리율을 제한한다.
* 기준을 초과하는 요청에 대해선 429(Too many request) 코드를 반환한다.

<figure><img src="/files/MgJ4JBonbLMG1djxKNtK" alt=""><figcaption><p>미들웨어로 동작하는 처리율 제한 장치 예시</p></figcaption></figure>

* 이 때 중요한 것은 기존에 사용하던 스택에서 큰 비용이 들지 않고 유연한 시스템을 구축하는 것이다. 프로그래밍 언어, 캐시 서비스 등 기존에 사용하던 것들이 유용하므로 선제적인 확인이 필요하다.
* 모든 것을 새로 구현한다면 상관없지만, 기존에 사용하던 게이트웨이 서비스가 있다면 얘기가 다르다. 게이트웨이의 규칙에 따라 처리율을 제한할 수 있는 방법이 있을지 찾아야한다.
* 처리율 제한 서비스를 만드는데는 비용이 들어가니 상용 서비스를 쓰는 것을 고려해볼 수도 있다.
* 처리율 제한 장치를 만들고 요청자 별 카운터를 기록하는 위치는 디스크보다 메모리가 훨씬 효율적이다. (빠르고 휘발성을 띄기 때문에) 일례로 Redis는 처리율 제한 장치를 구현할 때 많이 사용되고, 명령어로 `INCR (카운터 1 증가)`, `EXPIRE (카운터에 타임아웃 값을 설정하고 이 시간이 경과되면 카운터가 삭제된다)`를 지원한다.

***

#### 3. 상세 설계

* 처리율 한도 초과 여부 및 기준치를 클라이언트로 돌려줄 필요가 있을 땐 HTTP 헤더를 통해 전달이 가능하다.
  * `X-Ratelimit-Remaining`: 윈도 내 남은 처리 가능 횟수
  * `X-Ratelimit-Limit`: 매 윈도마다 클라이언트가 전송할 수 있는 요청의 수
  * `X-Ratelimit-Retry-After`: 한도 제한에 걸리지 않으려면 몇 초 뒤에 요청을 다시 보내야 하는지 알림

<figure><img src="/files/eIOuRKKVbygfsFKrGrc9" alt="" width="563"><figcaption></figcaption></figure>

* 클라이언트 요청은 서버가 아닌 미들웨어를 먼저 거친다. 이 부분에서 Redis에 저장된 카운터를 확인하고, 증가시킨 뒤 그 결과에 따라 요청을 서버로 전달하거나 폐기 혹은 메시지 큐에 삽입하여 후행 처리되게 구성한다.
