피드로 돌아가기
3 Hours Wasted on asyncio Pitfalls That Almost Took Down Production
Dev.toDev.to
Backend

asyncio 도입을 통한 크롤러 처리 시간 20분에서 2분으로 단축

3 Hours Wasted on asyncio Pitfalls That Almost Took Down Production

BAOFUFAN2026년 5월 1일5intermediate

Context

동기식 requests 라이브러리 기반의 순차적 처리로 인한 데이터 수집 지연 발생. 비즈니스 요구사항인 5분 이내 완료 대비 실제 처리 시간인 20분 사이의 간극으로 인한 타임아웃 발생률 40% 기록.

Technical Solution

  • Event Loop 기반의 Cooperative Scheduling 도입을 통한 IO-bound 작업의 CPU 유휴 시간 최소화
  • requests 라이브러리를 aiohttp로 대체하여 Coroutine 내 Blocking Call 제거 및 제어권 반환 구조 설계
  • asyncio.gather()의 return_exceptions=True 옵션 설정을 통한 개별 태스크 예외 발생 시 전체 배치 취소 방지
  • asyncio.Semaphore를 이용한 동시성 제어로 File Descriptor 고갈 및 대상 서버 Rate Limiting 유발 차단
  • Exponential Backoff 기반의 재시도 메커니즘 결합을 통한 일시적 네트워크 장애 대응력 강화

Impact

  • 전체 데이터 수집 소요 시간 20분에서 2분 미만으로 단축
  • 단일 요청 평균 1.2초 소요 작업의 동시 처리로 인한 처리 효율 극대화

Key Takeaway

단일 스레드 기반의 비동기 프로그래밍에서는 단 하나의 Blocking Call이 전체 Event Loop를 중단시키므로, 모든 IO 라이브러리의 비동기 호환성 검증이 필수적임.


- Coroutine 내부에서 time.sleep() 대신 await asyncio.sleep() 사용 여부 확인 - asyncio.gather() 사용 시 예외 전파 방지를 위한 return_exceptions 설정 검토 - 대규모 동시 요청 시 시스템 자원 보호를 위한 Semaphore 기반의 Concurrency Limit 설정 - 비동기 HTTP 클라이언트(aiohttp, httpx) 도입을 통한 Blocking IO 제거

원문 읽기