Next.js에서 5개의 키 로테이션 시스템으로 월 15만 건의 무료 API 호출을 처리하는 방법
요약
Google Gemini의 무료 티어 제한을 극복하기 위해 Next.js 환경에서 5개의 API 키를 로테이션하는 시스템 구축 방법을 설명합니다. 라운드 로빈 방식과 429 오류 발생 시 자동 페일오버 기능을 통해 월 최대 22.5만 건의 요청을 무료로 처리하는 기술적 노하우를 다룹니다.
핵심 포인트
- 라운드 로빈 방식을 통한 API 부하 균등 분산
- 429 Rate Limit 오류 발생 시 즉각적인 키 페일오버 구현
- Modulo 연산자를 활용한 순환 구조 설계
- 서버리스 환경에 최적화된 메모리 기반 키 관리
대부분의 무료 티어 (Free-tier) API는 분당 15회의 요청을 제공합니다. 사이드 프로젝트에는 괜찮지만, 도구에 실제 트래픽이 들어오기 시작하면 이야기가 달라집니다. 저는 4개의 AI 기반 기능(요약기, 문법 검사기, 패러프레이저, 에세이 작성기)을 포함하여 61개의 도구를 제공하는 무료 툴킷인 ToolForge를 구축했습니다. 이 모든 기능은 Google Gemini의 무료 티어를 기반으로 작동합니다. 과제는 다음과 같습니다: 분당 15회 요청 × 키 1개 = 사용자 15명 이후 도구 작동 중단. 해결책은 자동 장애 조치 (Failover) 기능을 갖춘 5개의 API 키를 로테이션하는 것입니다.
문제점
Gemini의 무료 티어는 관대합니다. 키당 분당 15회, 일일 1
status } ` ); } // 성공 — 다음 요청을 위해 키 로테이션 (부하 분산) currentKeyIndex = ( currentKeyIndex + 1 ) % API_KEYS . length ; const data = await response . json (); return data . candidates ?.[ 0 ]?. content ?. parts ?.[ 0 ]?. text || '' ; } catch ( error ) { currentKeyIndex = ( currentKeyIndex + 1 ) % API_KEYS . length ; if ( attempt === maxAttempts - 1 ) throw error ; } } throw new Error ( ' 모든 API 키가 소진되었습니다 ' ); }
작동 원리
기본적으로 라운드 로빈 (Round-robin) 방식: 각 요청은 순서대로 다음 키를 사용합니다. 이를 통해 부하를 균등하게 분산합니다. 즉, 키 1이 요청 1을 처리하고, 키 2가 요청 2를 처리하는 방식입니다.
429 오류 시 자동 페일오버 (Failover): 특정 키가 속도 제한 (Rate-limited)에 걸리면, 루프는 즉시 다음 키로 시도합니다. 지연 시간이나 재시도 타이머가 필요 없습니다.
순환 구조: 5번 키를 사용한 후에는 다시 1번 키로 돌아갑니다. 나머지 연산자 (Modulo operator)가 이 역할을 수행합니다.
외부 상태 없음: currentKeyIndex는 서버 메모리에 상주합니다. 단일 Vercel 서버리스 함수 (Serverless function) 환경에서는 이 방식이 완벽하게 작동합니다. 멀티 인스턴스 배포 환경이라면 Redis를 사용하는 것이 좋겠지만, 현재 규모에서는 이 정도로 충분합니다.
수치 계산
| 키 개수 | 분당 요청 수 | 일일 요청 수 | 월간 요청 수 |
|---|---|---|---|
| 1개 | 15 | 1,500 | 45,000 |
| 3개 | 45 | 4,500 | 135,000 |
| 5개 | 75 | 7,500 | 225,000 |
5개의 키를 사용하면 분당 75회, 월간 225,000회의 동시 요청을 모두 무료 티어 (Free tier)로 처리할 수 있습니다.
API 라우트에서 사용하기
모든 AI 도구는 동일한 함수를 호출합니다:
// src/app/api/summarize/route.ts
import { fetchWithKeyRotation } from ' @/lib/gemini-keys ' ;
export async function POST ( req : Request ) {
const { text } = await req . json ();
const prompt = `다음 텍스트를 3~5문장으로 요약하세요:
${ text } ` ;
const summary = await fetchWithKeyRotation ( prompt );
return Response . json ({ summary });
}
AI 요약기, 문법 검사기, 패러프레이저 (Paraphraser), 에세이 작성기 모두 정확히 동일한 fetchWithKeyRotation() 함수를 사용합니다. 새로운 AI 도구를 추가하는 데는 10분도 걸리지 않습니다. 다른 프롬프트(Prompt)를 가진 새로운 API 라우트를 만들기만 하면 됩니다.
사용자 속도 제한 (키뿐만 아니라)
키는 API 측의 제한을 처리합니다.
하지만 개별 사용자가 모든 키를 소진하는 것도 방지해야 합니다:
// 간단한 IP 기반 속도 제한 (rate limit)
const rateLimitMap = new Map<string, number[]>();
function isRateLimited(ip: string, maxRequests = 5, windowMs = 60000) {
const now = Date.now();
const timestamps = rateLimitMap.get(ip) || [];
const recent = timestamps.filter(t => now - t < windowMs);
if (recent.length >= maxRequests) return true;
recent.push(now);
rateLimitMap.set(ip, recent);
return false;
}
이 방식은 각 사용자에게 분당 5회의 요청을 허용합니다. 이는 실제 사용에는 충분하지만, 남용하기에는 부족한 수치입니다.
배운 점들
한계치를 고려하여 아키텍처를 설계한다면 무료 티어 (Free tier)도 대규모로 운영 가능합니다. 창의적인 해결책을 모두 시도해 보기 전까지는 유료 API (Paid API)를 기본값으로 선택하지 마세요.
라운드 로빈 (Round-robin) 방식이 무작위 선택 (Random selection)보다 낫습니다. 무작위 방식은 동일한 키를 두 번 호출할 수 있지만, 라운드 로빈은 균등한 분배를 보장합니다. 또한 실패했을 때뿐만 아니라, 성공한 후에도 항상 키를 로테이션 (Rotate) 하세요. 이는 특정 키가 트래픽의 90%를 처리하고 다른 키들은 유휴 상태로 방치되는 것을 방지합니다.
키 사용량을 모니터링하세요. 우리는 어떤 키가 각 요청을 처리했는지 로그를 남깁니다. 이를 통해 특정 키가 지속적으로 속도 제한 (Rate-limited)에 걸리는지(즉, 트래픽이 용량을 초과했는지) 알 수 있습니다.
직접 체험해 보세요
4개의 AI 도구가 freetoolforge.org에서 라이브 상태로 무료 제공됩니다:
- AI 텍스트 요약기 (AI Text Summarizer)
- AI 문법 검사기 (AI Grammar Checker)
- AI 문장 재구성기 (AI Paraphraser)
- AI 에세이 작성기 (AI Essay Writer)
각 도구는 단 한 번의 유료 API 호출 없이도 매일 수백 명의 사용자를 처리합니다.
제작자: Abid Niazi — Full Stack Developer, Pakistan
ToolForge: freetoolforge.org — 61개의 무료 도구, 광고 없음, 회원가입 없음
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기