FastAPI 요청 처리 흐름 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

1. FastAPI의 기본 구조

  • FastAPI는 Python으로 작성된 ASGI 앱
  • 일반적으로 uvicorn ASGI 서버 위에서 실행
  • uvicorn main:appmain.py의 FastAPI 인스턴스(app)를 불러와 이벤트 루프에 등록

2. 요청 수신 및 처리 흐름 (소켓 수신부터 ready 큐까지)

a. 소켓 레벨에서의 흐름

  1. uvicorn 실행 시 서버 프로세스가 생성되고, 메인 스레드에 asyncio 이벤트 루프가 생성됨
  2. 설정된 호스트/포트에 대해 리스닝 소켓을 커널에 요청 (socket → bind → listen)
  3. 클라이언트가 요청을 보내면 커널이 TCP 3-way handshake를 처리하고, 연결 정보를 리스닝 큐에 저장
  4. 이벤트 루프가 epoll/select로 리스닝 큐를 감지하여 새로운 연결을 accept
  5. 커널은 클라이언트별 연결 소켓을 생성하고 데이터 수신 대기 상태로 진입

b. 이벤트 루프에서의 처리 흐름

  1. 연결된 소켓에 요청 데이터가 도착하면, 이벤트 루프가 이를 감지하고 FastAPI 애플리케이션에 전달
  2. FastAPI는 내부적으로 Starlette 라우터를 사용하여 URL/HTTP 메서드에 따라 핸들러 함수 탐색
  3. 핸들러가 def로 정의된 동기 함수인 경우:
    • ThreadPoolExecutor에 작업을 위임 (offload)
    • 이벤트 루프는 이 작업에 대해 Future 객체를 생성하고 콜백 정보를 저장함
    • 사용 가능한 워커 스레드가 작업 큐에서 이 함수를 가져가 실행
    • 작업이 완료되면, 워커 스레드는 future.set_result()를 호출하여 이벤트 루프에 완료 알림
    • 이벤트 루프는 해당 콜백을 ready 큐에 등록하고 다음 틱에 실행
  4. 핸들러가 async def일 경우:
    • asyncio 이벤트 루프가 직접 해당 코루틴을 실행
    • await 지점을 만나면 현재 작업은 일시 중단되고 루프는 다른 코루틴 작업으로 전환