FastAPI에서 OpenAI API 호출 한도 우회 및 부하 분산을 위한 초간단 라운드로빈 구조

김한결김한결
2 min read

Overview

GPT API 쓰다 보면 429 Too Many Requests 에러 본 적 있을 거다. 이건 OpenAI API가 API Key 단위로 호출 한도를 두고 있기 때문이다. 그래서 실무에선 여러 개의 Key를 순환하면서 쓰는 구조가 필요하다.

그 중에서도 라운드로빈(Round-Robin) + 스레드 안전 처리를 적용한 구조가 가장 단순하면서 안정적이다.


Summary

  • 여러 OpenAI API Key를 순환하며 사용

  • 호출 한도(rate limit) 우회

  • 트래픽 분산 및 API 부하 감소

  • 다중 스레드 환경에서도 안정적인 처리


Sample Code

import threading

gpt_lock = threading.Lock()

def get_next_gpt_endpoint():
    global gpt_last_index
    with gpt_lock:  # 동시성 제어: 하나의 스레드만 접근 허용
        gpt_last_index = (gpt_last_index + 1) % len(gpt_endpoints)
        endpoint = gpt_endpoints[gpt_last_index]
        apikey = gpt_apikeys[gpt_last_index]
    return endpoint, apikey

threading.Lock() 왜 쓰는가?

  • FastAPI + Uvicorn, Gunicorn, Flask 등 멀티스레드 환경에선 gpt_last_index가 동시에 수정될 수 있음

  • 이걸 방지하려면 Mutex(상호 배제) 필요

  • with gpt_lock: 사용 시 블록 탈출과 동시에 자동으로 release()

라운드로빈 방식의 장점

  • Key 사용을 고르게 분산: 특정 키에 부하 몰리지 않음

  • 단순함: 복잡한 상태 관리 없이 구현 가능

  • 효율적: 무작위 선택보다 더 예측 가능하고 디버깅 쉬움


Conclusion

항목효과
호출 한도 분산여러 Key로 분산하여 limit 우회
부하 분산특정 엔드포인트 집중 방지
안정성Race condition 방지
성능병렬 환경에서도 안전하게 작동

Future Work

현재는 Key가 모두 정상이라고 가정한 구조다. 하지만 실전에서는 어떤 Key가 이미 사용량 초과 되었을 수도 있다.

Idea

  • 각 Key의 상태/남은 quota 를 추적해서 사용

  • Redis 등에 Key 상태를 저장하고, “사용 가능 여부 기반으로 선택”

  • 실패 횟수 누적 시 일정 시간 패널티 주기

0
Subscribe to my newsletter

Read articles from 김한결 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

김한결
김한결