FastAPI 요청 처리 흐름 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
1. FastAPI의 기본 구조
- FastAPI는 Python으로 작성된 ASGI 앱
- 일반적으로
uvicorn
ASGI 서버 위에서 실행
uvicorn main:app
→ main.py
의 FastAPI 인스턴스(app
)를 불러와 이벤트 루프에 등록
2. 요청 수신 및 처리 흐름 (소켓 수신부터 ready 큐까지)
a. 소켓 레벨에서의 흐름
uvicorn
실행 시 서버 프로세스가 생성되고, 메인 스레드에 asyncio 이벤트 루프가 생성됨
- 설정된 호스트/포트에 대해 리스닝 소켓을 커널에 요청 (socket → bind → listen)
- 클라이언트가 요청을 보내면 커널이 TCP 3-way handshake를 처리하고, 연결 정보를 리스닝 큐에 저장
- 이벤트 루프가 epoll/select로 리스닝 큐를 감지하여 새로운 연결을 accept
- 커널은 클라이언트별 연결 소켓을 생성하고 데이터 수신 대기 상태로 진입
b. 이벤트 루프에서의 처리 흐름
- 연결된 소켓에 요청 데이터가 도착하면, 이벤트 루프가 이를 감지하고 FastAPI 애플리케이션에 전달
- FastAPI는 내부적으로 Starlette 라우터를 사용하여 URL/HTTP 메서드에 따라 핸들러 함수 탐색
- 핸들러가
def
로 정의된 동기 함수인 경우:
ThreadPoolExecutor
에 작업을 위임 (offload)
- 이벤트 루프는 이 작업에 대해
Future
객체를 생성하고 콜백 정보를 저장함
- 사용 가능한 워커 스레드가 작업 큐에서 이 함수를 가져가 실행
- 작업이 완료되면, 워커 스레드는
future.set_result()
를 호출하여 이벤트 루프에 완료 알림
- 이벤트 루프는 해당 콜백을 ready 큐에 등록하고 다음 틱에 실행
- 핸들러가
async def
일 경우:
- asyncio 이벤트 루프가 직접 해당 코루틴을 실행
await
지점을 만나면 현재 작업은 일시 중단되고 루프는 다른 코루틴 작업으로 전환