Python asyncio로 API 호출 속도 개선하기

문제 상황

사용자 데이터를 외부 API로 전송하는 배치 작업이 있었다. 5000명 분량을 처리하는데 12분 정도 걸렸는데, 각 API 호출을 순차적으로 처리하고 있었다.

import requests

def sync_process(users):
    results = []
    for user in users:
        response = requests.post(API_URL, json=user)
        results.append(response.json())
    return results

asyncio 적용

aiohttp와 asyncio를 사용해서 동시 처리로 전환했다. semaphore로 동시 요청 수를 제한했다.

import asyncio
import aiohttp

async def fetch_user(session, user, semaphore):
    async with semaphore:
        async with session.post(API_URL, json=user) as response:
            return await response.json()

async def async_process(users):
    semaphore = asyncio.Semaphore(50)  # 동시 50개
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_user(session, user, semaphore) for user in users]
        return await asyncio.gather(*tasks)

if __name__ == '__main__':
    results = asyncio.run(async_process(users))

결과

  • 실행 시간: 12분 → 2분
  • Semaphore 값을 50으로 설정했는데, 외부 API rate limit과 서버 부하를 고려한 값이다
  • 에러 핸들링은 각 task에 try-except를 추가해서 일부 실패해도 전체가 멈추지 않도록 처리했다

주의사항

동시 요청 수를 너무 높이면 상대 서버에서 429 에러를 내거나, 우리 서버의 네트워크 리소스가 고갈될 수 있다. 모니터링하면서 적절한 값을 찾아야 한다.