[개발] 프로그램 지식

[server] 429 Too Many Requests 에러란? 원인 및 해결방법

  • -
반응형

429 Too Many Requests: 원인과 해결 방법

1. 429 Too Many Requests란?

429 Too Many Requests는 클라이언트가 일정 시간 동안 너무 많은 요청을 보냈을 때 서버가 반환하는 HTTP 상태 코드입니다. 주로 API 호출 시 요청 제한(레이트 리미트, Rate Limit)을 초과했을 때 발생합니다.

 

 

 

 

 

2. 주요 원인

  • 레이트 리미트 초과: 클라이언트가 서버의 요청 허용 한도를 초과.
  • 봇 트래픽: 자동화된 스크립트나 봇이 과도한 요청을 보냈을 때.
  • 서버 보호 메커니즘: DoS(서비스 거부 공격)를 방지하기 위한 서버 설정.

 

 

 

 

 

3. 429 에러의 영향

이 에러는 클라이언트의 요청이 차단되어 서버와의 통신이 중단될 수 있으며, 다음과 같은 부정적인 영향을 미칩니다:

  • 사용자 경험 저하: 서비스 응답이 느리거나 차단됨.
  • API 사용 제한: 클라이언트 애플리케이션의 기능이 제한됨.

 

 

 

 

 

 

 

4. 해결 방법

1) 클라이언트 요청 속도 줄이기

API 요청 빈도를 줄여 서버가 설정한 한도를 초과하지 않도록 합니다. 예:


// JavaScript Fetch 예제
function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function fetchData() {
  for (let i = 0; i < 5; i++) {
    await fetch('https://example.com/api')
      .then(response => response.json())
      .then(data => console.log(data));
    await wait(1000); // 1초 대기
  }
}
fetchData();

 

 

 

 

 

2) 서버의 Rate Limit 정책 확인

API 문서에서 요청 제한 정보를 확인하고, 클라이언트가 해당 한도를 준수하도록 구현합니다.

 

 

 

 

 

3) Retry-After 헤더 처리

서버가 Retry-After 헤더를 반환하는 경우, 지정된 시간 후에 요청을 다시 시도합니다.


// JavaScript Fetch 예제
fetch('https://example.com/api')
  .then(response => {
    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 1; // 기본값: 1초
      console.log(`429 에러 발생. ${retryAfter}초 후 재시도합니다.`);
      setTimeout(() => fetch('https://example.com/api'), retryAfter * 1000);
    }
  });

 

 

 

 

 

 

4) 캐싱 활용

동일한 데이터에 대한 반복 요청을 줄이기 위해 캐싱을 활용합니다.


// 간단한 캐싱 예제
let cache = {};

async function getData(url) {
  if (cache[url]) {
    return cache[url];
  }
  const response = await fetch(url);
  const data = await response.json();
  cache[url] = data;
  return data;
}

 

 

 

 

 

5) API 키를 분리

한 프로젝트에서 여러 API 키를 사용하여 요청을 분산합니다(가능한 경우).

 

 

 

 

 

 

 

 

5. 예제 코드

Python Flask에서 Rate Limit을 구현하는 예제:


from flask import Flask, request, jsonify
from time import time

app = Flask(__name__)

requests_store = {}
LIMIT = 5  # 허용 요청 수
TIME_WINDOW = 60  # 시간 제한 (초)

@app.route('/api', methods=['GET'])
def api():
    client_ip = request.remote_addr
    now = time()

    if client_ip not in requests_store:
        requests_store[client_ip] = []

    requests_store[client_ip] = [t for t in requests_store[client_ip] if now - t < TIME_WINDOW]

    if len(requests_store[client_ip]) < LIMIT:
        requests_store[client_ip].append(now)
        return jsonify({"message": "요청 성공"})
    else:
        return jsonify({"error": "429 Too Many Requests"}), 429

if __name__ == '__main__':
    app.run(debug=True)

 

 

 

 

 

 

6. 관련 HTTP 상태 코드

  • 403 Forbidden: 접근이 거부되었을 때.
  • 503 Service Unavailable: 서버가 요청을 처리할 준비가 되지 않았을 때.
  • 408 Request Timeout: 요청이 일정 시간 내에 완료되지 않았을 때.

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.