WEB
[Python Backend] FastAPI를 이해하기 위한 비동기 처리 개념 정리
땽뚕
2025. 5. 25. 09:39
728x90
[python backend] FastAPI를 이해하기 위한 비동기 처리 개념 정리
그렇다 FastAPI가 빠른 이유는 비동기 지원으로 인한 것
그럼 당최 비동기란 뭐고 그거 어떻게 하는 건데?
* 이전 포스트에서 이어집니다 (https://asidefine.tistory.com/330)
* 이후 포스트로 이어집니다 (https://asidefine.tistory.com/328) (https://asidefine.tistory.com/334)
1. 동기(Synchronous) vs 비동기(Asynchronous)
동기
- 작업이 순차적으로 실행됨
- A 작업이 끝나야만 B 작업이 실행 가능
- CPU는 일을 하지 않고 대기 중일 수도 있음
def cook():
boil_water()
cook_rice()
serve()
cook() # 위 작업은 순차적으로 실행됨
비동기
- 작업 간의 대기가 있을 경우, 그 시간에 다른 작업을 처리함
- I/O(입출력) 대기 시간 동안 CPU가 다른 작업 처리 가능
- 사용자 경험(UX) 개선에 도움됨
async def cook():
await boil_water()
await cook_rice()
await serve()
2. 동시성(Concurrency) vs 병렬성(Parallelism)
동시성
- 한 번에 하나의 작업만 처리하지만 여러 작업을 짧은 시간 간격으로 번갈아 수행
- 멀티태스킹처럼 보이지만 실제로는 빠른 스위칭
- 코루틴이나 스레드를 이용해 구현 가능
병렬성
- 여러 작업을 동시에 실행함
- 멀티코어 CPU 환경에서 여러 프로세스가 각기 다른 코어에서 동시 실행
- CPU 바운드 작업에서 효과적
동시성 병렬성 사용 자원 하나의 CPU (단일코어) 여러 CPU (멀티코어) 구현 방법 코루틴, 스레드 멀티프로세스 적합한 작업 I/O 바운드 CPU 바운드
3. 파이썬 비동기 프로그래밍 핵심: 코루틴과 async/await
코루틴이란?
- 일반 함수처럼 생겼지만 중간에 멈췄다가 다시 실행할 수 있음
- async def로 정의된 함수는 코루틴 객체 반환
- 코루틴 객체는 await 키워드로 실행
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
asyncio.run(say_hello())
await의 역할
- 다른 비동기 작업이 끝날 때까지 기다림
- 동기적으로 보면 멈춘 것 같지만, 실제로는 그동안 다른 코루틴이 실행됨
4. asyncio: 파이썬 비동기 실행의 핵심 모듈
asyncio가 필요한 이유
- 코루틴은 단독으로 실행되지 않음
- 이벤트 루프를 통해 실행 스케줄링이 필요
- asyncio가 이 역할을 담당
주요 함수 및 메커니즘
- asyncio.run(coro): 메인 루프 실행
- asyncio.create_task(coro): 작업 등록 (백그라운드 실행)
- asyncio.gather(*coros): 여러 코루틴을 병렬로 실행
import asyncio
async def job(name, delay):
print(f"{name} 시작")
await asyncio.sleep(delay)
print(f"{name} 종료")
async def main():
await asyncio.gather(
job("A", 2),
job("B", 1),
job("C", 3)
)
asyncio.run(main())
- 실행 순서
- A, B, C 순차 시작
- 각각 await로 멈추는 동안 다른 작업 실행
- 전체 실행 시간은 가장 오래 걸리는 작업 시간만큼
5. FastAPI에서 async 활용하기
- FastAPI란?
- Python 기반 비동기 웹 프레임워크
- async def 함수 기반으로 경량 HTTP 서버를 빠르게 구성 가능
- Pydantic을 이용한 데이터 검증, 자동 문서화(OpenAPI 지원) 포함
- 동기/비동기 핸들러 비교
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/sync")
def sync_route():
import time
time.sleep(1)
return {"message": "sync"}
@app.get("/async")
async def async_route():
await asyncio.sleep(1)
return {"message": "async"}
- /sync: sleep 동안 서버는 블로킹됨
- /async: sleep 중 다른 요청을 처리 가능
- 언제 async로 작성해야 할까?
- 외부 API 요청
- 파일, 데이터베이스, 네트워크 I/O
- 사용자 요청이 많을 때 병렬 처리 필요할 경우
6. uvicorn: FastAPI를 실행하는 ASGI 서버
- FastAPI는 API를 정의하는 웹 애플리케이션 프레임워크라면, Uvicorn은 이 FastAPI 앱을 실행시키는 웹 서버(ASGI 서버)다
FastAPI | Uvicorn | |
종류 | 웹 프레임워크 | ASGI 서버 (웹 서버) |
역할 | 라우팅, 요청 처리, API 로직 정의 | 클라이언트 요청을 받고 FastAPI에 전달, 응답 반환 |
예시 | /hello 요청 시 어떤 함수를 실행할지 정의 | 클라이언트로부터 HTTP 요청을 받아 FastAPI에게 전달 |
실행 방법 | 코드로 정의만 함 (FastAPI() 인스턴스 생성) | uvicorn main:app 명령어로 실행 |
비유 | "앱의 본체 (뇌와 몸)" | "앱을 외부에 노출시키는 입구 (입과 귀)" |
❓ 웹 서버가 뭔데 ?
- 인터넷을 통해서 브라우저의 요청을 받아, 요청한 웹페이지, API Responsse, 파일 등을 반환해주는 소프트웨어
- 정적 웹 서버 : Nginx, Apache
- 동적 웹 서버 (Python용) : Uvicorn (ASGI), Gunicorn (WSGI)
- WSGI vs ASGI이란 ?
- WSGI(Flask, Django):
- Web Server Gateway Interface
- 동기만 지원
- ASGI(FastAPI):
- Asynchronous Server Gateway Interface
- 비동기 지원 → 고성능 I/O 처리 가능
- WSGI(Flask, Django):
- uvicorn이란?
- ASGI 서버로, FastAPI 같은 비동기 프레임워크 실행을 담당
- 기본적으로 비동기 코드를 빠르게 실행하고 요청을 비동기적으로 처리함
- 실행 명령
uvicorn main:app --reload
# main: 파일 이름 (main.py)
# app: FastAPI 객체
# uvicorn main:app --reload
- uvicorn 내부 동작
- 실제로도 비동기를 위해서 asyncio를 사용해서 비동기 함수 실행 시킴 - 이를 통해 별도의 Thread 생성 없이 동시성 구현
#https://github.com/encode/uvicorn/blob/master/uvicorn/server.py#L51
class Server:
...
def run(self, sockets: list[socket.socket] | None = None) -> None:
self.config.setup_event_loop()
return asyncio.run(self.serve(sockets=sockets))
- 마무리 정리: 전체 개념 흐름
- 동기 vs 비동기
→ 작업 흐름과 기다림의 차이 - 동시성 vs 병렬성
→ 하나의 CPU로도 동시처리 가능 (코루틴), 병렬은 멀티코어 필요 - async/await 문법
→ 파이썬에서 비동기 코드를 작성하는 공식적인 방법 - asyncio
→ 코루틴을 실행 및 관리하는 이벤트 루프 제공 - FastAPI
→ async 기반으로 고성능 웹 서버 구성 가능 - uvicorn
→ FastAPI를 실행시키는 고성능 ASGI 서버
Reference.
- https://jellybeanz.medium.com/cgi-wsgi-asgi-%EB%9E%80-cgi-wsgi-asgi-bc0ba75fa5cd
- https://youtu.be/zAvWv_Wi0z0?si=P-o0Vu7T7fu1tXAY
- https://sean-j.tistory.com/entry/FastAPI-%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%85%8C%EC%8A%A4%ED%8A%B8
- https://velog.io/@jaebig/python-%EB%8F%99%EC%8B%9C%EC%84%B1-%EA%B4%80%EB%A6%AC-3-%EC%BD%94%EB%A3%A8%ED%8B%B4Coroutine
- https://docs.python.org/ko/3.13/library/asyncio-task.html
- https://devocean.sk.com/blog/techBoardDetail.do?ID=165922&boardType=techBlog
- https://jongsky.tistory.com/91
- https://lsjsj92.tistory.com/648
728x90