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 에러를 내거나, 우리 서버의 네트워크 리소스가 고갈될 수 있다. 모니터링하면서 적절한 값을 찾아야 한다.