FastAPI๋ ๋์ ์ฌ์ฉ์ฑ๊ณผ ๋น ๋ฅธ ์๋๋ฅผ ์๋ํ๋ Python ์น ํ๋ ์์ํฌ์ ๋๋ค.
FastAPI์ ํน์ง
๋น ๋ฅธ ์ฑ๋ฅ
FastAPI์ ๊ธฐ์์ ์ฐพ์ ์ฌ๋ผ๊ฐ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
graph LR A[Cython, libuv] --> B[uvloop] B --> C["Uvicorn (ASGI)"] C --> D[Starlette] D --> E[FastAPI]
์ฌ๊ธฐ์ Cython์ C๋ก ์ปดํ์ผ๋์ด ๋งค์ฐ ๋น ๋ฅธ ์๋๋ฅผ ์๋ํ๊ณ , libuv๋ C๋ก ์์ฑ๋ ์ด๋ฒคํธ ๊ธฐ๋ฐ I/O ์์ง์ผ๋ก FastAPI๋ฟ ์๋๋ผ Node.js ๋ฑ์์๋ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค. ๊ทธ๋์ ๊ณต๊ฐ ๋น์์๋ FastAPI์ ๋ชจ์ฒด์ธ Starlette, Uvicorn ์ ๋๋ฅผ ์ ์ธํ๋ฉด ๋ฒค์น๋งํฌ ์ฑ๋ฅ์ด ์ ์ผ ์ข์์ต๋๋ค.
๋ฌผ๋ก Node.js๋ Go์ ์ฑ๋ฅ์ด ๋ฏธ์น์ง๋ ๋ชปํฉ๋๋ค.1 ๊ทธ๋๋ ๊ฒ์ฆ๋ Python ์น ํ๋ ์์ํฌ ์ค์์๋ ์ ์ผ ๋น ๋ฆ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ ๊ฒฝํ
๊ณต์ ๋ฌธ์๊ฐ ๋งค์ฐ ์ ๋์ด ์์ต๋๋ค.
์ฝ๊ณ , ํธํ๊ณ , Python ์น ์
๋ฌธ์ฉ์ผ๋ก ์ข์ต๋๋ค. ์ค๋ฌด์์ ์ฌ์ฉํ๊ธฐ์๋ ์ ํ ๋ฌด๋ฆฌ๊ฐ ์์ต๋๋ค. ์ฑ๋ฅ์ด ์ข์ ํ๋ ์์ํฌ๊ฐ ๋ง์ ์์ค์๋ PoC๋ ๊ฐ๋จํ๊ฒ ๋ฌด์ธ๊ฐ๋ฅผ ๋ง๋ค๊ธฐ ์ข์ ๊ณ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์ค์น ๋ฐ ๋ฐฐํฌ
์ค์น ์ ์ฃผ์ ์ฌํญ
๋ฐ๋์ standard
์ต์
์ผ๋ก ์ค์นํด์ผ uvloop
์ ์ฌ์ฉํ ์ ์๊ณ FastAPI์ ์ฑ๋ฅ์ ๋๋ฆด ์ ์์ต๋๋ค.2
์ต์
์ ๋นผ๊ณ ์ค์นํ๋ฉด ์์ Python ๊ธฐ๋ฐ์ผ๋ก ๋์ํฉ๋๋ค.
pip install 'uvicorn[standard]'
์๋ ๋ช ๋ น์ด๋ก FastAPI์ ํจ๊ป ์ค์นํ ์๋ ์์ต๋๋ค.
pip install "fastapi[all]"
๋ฐฐํฌ ๋ฐฉ์
-
์ผ๋ฐ์ ์ธ ํํ์ ๋ฐฐํฌ๋ผ๋ฉด, NGINX + Uvicorn worker๊ฐ ๋ฌด๋ํ ์กฐํฉ์ ๋๋ค.
- NGINX
- Uvicorn๋ ๋ ๋ฆฝ์ ์ธ ์น ์๋ฒ์ ์ญํ ์ ํ ์๋ ์์ง๋ง, ํ์คํ ์ญํ ๋ถ๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
- NGINX๋ C๋ก ๊ตฌํ๋์ด ์ฑ๋ฅ์ด ์ข๊ณ , Reverse Proxy ๋ฑ ์ญํ ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ง์ด ์กฐํฉํฉ๋๋ค.
- ์ ์ ๋ฆฌ์์ค, ๋ผ์ฐํ ๋ฑ์ NGINX์์ ์ฒ๋ฆฌํ๊ณ ๋์ ์ธ ์์ฒญ์ Uvicorn์ด ์ํํ๊ฒ ๋ฉ๋๋ค.
- Uvicorn worker
- ๊ณต์ ๋ฌธ์์์๋ ๊ถ์ฅํ๋ ๋ฐฉ์์ ๋๋ค.3
- ์ฒ๋ฆฌ๋์ ๋๋ฆฌ๊ธฐ ์ํด ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ํ์ฉํฉ๋๋ค.
- ๋ฉํฐ ์ค๋ ๋๋ ๋ฌผ๋ก ๊ฐ๋ฅํ์ง๋ง, Python์ GIL4 ๋ฌธ์ ๊ฐ ์์ง ํด๊ฒฐ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์์ง๊น์ง๋ Python์์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด์๋ ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- GIL๋ก ์ธํด ํน์ ์์ ์ ํ๋์ ์ค๋ ๋๋ง CPU ์์์ ์ ๊ทผ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ CPU ์์ ์๋ ํจ๊ณผ๊ฐ ์๊ฑฐ๋ ์คํ๋ ค ์ค๋ ๋ ์์ฑ๊ณผ GIL ์ ์ด ๋น์ฉ์ผ๋ก ์ธํด ์ฑ๋ฅ์ด ๋จ์ด์ง ์๋ ์์ต๋๋ค.
- ๋จ, I/O ์์ ์๋ ๋ฉํฐ ์ค๋ ๋๊ฐ ์ ํจํฉ๋๋ค.
- ๋ฉํฐ ์ค๋ ๋๋ ๋ฌผ๋ก ๊ฐ๋ฅํ์ง๋ง, Python์ GIL4 ๋ฌธ์ ๊ฐ ์์ง ํด๊ฒฐ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์์ง๊น์ง๋ Python์์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด์๋ ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ์ด์ ์๋ Gunicorn์ ๊ฐ์ด ์ฌ์ฉํ์ง๋ง, ํ์ฌ๋ ๊ณต์ ๊ฐ์ด๋์์๋ ๊ทธ๋ฅ
--workers
์ต์ ์ ์ฌ์ฉํ๋๋ก ๊ถ์ฅํ๊ณ ์์ต๋๋ค.
- NGINX
-
ํด๋ผ์ฐ๋ ๋๋ Kubernetes ํ๊ฒฝ์ ๊ฒฝ์ฐ, Uvicorn ๋จ์ผ ํ๋ก์ธ์ค๋ก ์ฌ๋ฌ ์ปจํ ์ด๋๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๊ฐ์ฅ ๋จ์ํ ํจํด์ ๋๋ค. ๋จ, ์ฑ๋ฅ์ด๋ ์ฑ์ ํน์ฑ์ ๋ฐ๋ผ ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
Proxy ๋ค์์ ์ฌ์ฉํ ๋
FastAPI๊ฐ NGINX Ingress Controller, Traefik ๋ฑ์ ํ๋ก์ ๋ค์์ ์๋ํ ๋๋ ์ฑ์์ root path๋ฅผ ๋ณ๋๋ก ์ง์ ํด์ผ ํฉ๋๋ค.5
์๋ฅผ ๋ค์ด, ์ด๋ฐ ์์ผ๋ก ์ค์ ํฉ๋๋ค.
from fastapi import FastAPI, Request
app = FastAPI(root_path="/api/v1")
๊ทธ ์ธ
- FastAPI์ ๊ด๋ จ๋ ๋ด์ฉ์ ์๋์ง๋ง, ๊ฐ๋ฐ์ฉ WSGI ์๋ฒ๋ ์ด์ ํ๊ฒฝ์ ์ ํฉํ์ง ์์ต๋๋ค.6
๋ํ์ ์ผ๋ก Flask์ Werkzeug๊ฐ ์์ต๋๋ค.
FastAPI๋ ํํ ๋ฆฌ์ผ์์๋ Uvicorn์ ์ฌ์ฉํ์ง๋ง, ์ด์ ํ๊ฒฝ๊ณผ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ฐจ์ด๋ฅผ ์ธ์งํ๊ณ ์์ด์ผ ํฉ๋๋ค.
์ฐธ๊ณ ์๋ฃ
FastAPI GitHub์ ๊ฒ์๊ธ์ ์ฐธ๊ณ ํ๋ฉด ์ฌ๋ฌ ์ฌ๋ก๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- How to maintain global pool of db connection and use it in each and every request?
- logs with FastAPI and Uvicorn