Python FastAPIμμ λΉλκΈ° μ²λ¦¬μ κ°λ ₯ν¨μ νμ©νμΈμ. μ΄ μ’ ν© κ°μ΄λλ λ°±κ·ΈλΌμ΄λ μμ , ꡬν, μ΄μ λ° νμ₯ κ°λ₯ν κΈλ‘λ² μΉ μ ν리μΌμ΄μ ꡬμΆμ μν λͺ¨λ² μ¬λ‘λ₯Ό μ΄ν΄λ΄ λλ€.
Python FastAPI λ°±κ·ΈλΌμ΄λ μμ : κΈλ‘λ² μ ν리μΌμ΄μ μ μν λΉλκΈ° μμ μ€ν λ§μ€ν°νκΈ°
μ€λλ μ μνΈ μ°κ²°λ λμ§νΈ νκ²½μμ λ§μ μμ μμ²μ ν¨μ¨μ μΌλ‘ μ²λ¦¬ν μ μλ μ ν리μΌμ΄μ μ ꡬμΆνλ κ²μ΄ κ°μ₯ μ€μν©λλ€. κΈλ‘λ² μ ν리μΌμ΄μ , νΉν λ€μν μ¬μ©μ κΈ°λ°κ³Ό μ§λ¦¬μ μΌλ‘ λΆμ°λ μ΄μμ μ²λ¦¬νλ μ ν리μΌμ΄μ μ κ²½μ° μ±λ₯κ³Ό μλ΅μ±μ λ°λμ§ν λΏλ§ μλλΌ νμμ μ λλ€. λΉ λ₯Έ μλμ κ°λ°μ μμ°μ±μΌλ‘ μ λͺ ν Pythonμ FastAPI νλ μμν¬λ κΈ°λ³Έ μμ²-μλ΅ μ£ΌκΈ°λ₯Ό μ°¨λ¨ν΄μλ μ λλ μμ μ κ΄λ¦¬νκΈ° μν κ°λ ₯ν μ루μ μ μ 곡ν©λλ€. λ°λ‘ λ°±κ·ΈλΌμ΄λ μμ μ λλ€.
μ΄ μ’ ν© κ°μ΄λλ FastAPIμ λ°±κ·ΈλΌμ΄λ μμ μ μμΈν μ΄ν΄λ³΄κ³ μλ λ°©μ, λΉλκΈ° μμ μ€νμ μ€μν μ΄μ , ν¨κ³Όμ μΌλ‘ ꡬννλ λ°©λ²μ μ€λͺ ν©λλ€. λ€μν μλ리μ€λ₯Ό λ€λ£¨κ³ , μΈκΈ° μλ μμ ν λΌμ΄λΈλ¬λ¦¬μμ ν΅ν©μ μ΄ν΄λ³΄κ³ , νμ₯ κ°λ₯νκ³ κ³ μ±λ₯ κΈλ‘λ² μΉ μλΉμ€λ₯Ό ꡬμΆνκΈ° μν μ€ν κ°λ₯ν ν΅μ°°λ ₯μ μ 곡ν©λλ€.
λ°±κ·ΈλΌμ΄λ μμ μ νμμ± μ΄ν΄
μ ν리μΌμ΄μ μμ μ¬μ©μκ° μκ°μ΄ μ€λ 걸리λ μμ μ μμνλ€κ³ μμν΄ λ³΄μΈμ. μ΄λ μλ‘ λ€λ₯Έ λλ₯μ κ±Έμ³ μμ² λͺ μ ꡬλ μμκ² λλ μ΄λ©μΌ 보λ΄κΈ°, λμ©λ μ΄λ―Έμ§ μ λ‘λ μ²λ¦¬, 볡μ‘ν λ³΄κ³ μ μμ± λλ λ€λ₯Έ μκ°λμ μ격 μλΉμ€μ λ°μ΄ν° λκΈ°ν λ± λͺ¨λ κ²μ΄ λ μ μμ΅λλ€. μ΄λ¬ν μμ μ΄ μμ² μ²λ¦¬κΈ° λ΄μμ λκΈ°μ μΌλ‘ μνλλ©΄ μ 체 μμ μ΄ μλ£λ λκΉμ§ μ¬μ©μμ μμ²μ΄ 보λ₯λ©λλ€. μ΄λ‘ μΈν΄ λ€μκ³Ό κ°μ λ¬Έμ κ° λ°μν μ μμ΅λλ€.
- μ μ‘°ν μ¬μ©μ κ²½ν: μ¬μ©μκ° μ₯μκ° κΈ°λ€λ¦¬κ² λμ΄ λΆλ§μ λλΌκ³ μ μ¬μ μΌλ‘ μ ν리μΌμ΄μ μ ν¬κΈ°νκ² λ©λλ€.
- μ€λ¨λ μ΄λ²€νΈ 루ν: FastAPI(asyncio μ¬μ©)μ κ°μ λΉλκΈ° νλ μμν¬μμ μ°¨λ¨ μμ μ μ 체 μ΄λ²€νΈ 루νλ₯Ό μ€λ¨μμΌ λ€λ₯Έ μμ²μ΄ μ²λ¦¬λμ§ μλλ‘ ν μ μμ΅λλ€. μ΄λ νμ₯μ±κ³Ό μ²λ¦¬λμ μ¬κ°ν μν₯μ λ―ΈμΉ©λλ€.
- μ¦κ°λ μλ² λ‘λ: μ₯κΈ° μ€ν μμ²μ μλ² λ¦¬μμ€λ₯Ό λ¬Άμ΄ μ ν리μΌμ΄μ μ΄ ν¨κ³Όμ μΌλ‘ μλΉμ€ν μ μλ λμ μ¬μ©μ μλ₯Ό μ€μ λλ€.
- μ μ¬μ μκ° μ΄κ³Ό: λ€νΈμν¬ μ€κ°μ λλ ν΄λΌμ΄μΈνΈλ μλ΅μ κΈ°λ€λ¦¬λ λμ μκ°μ΄ μ΄κ³Όλμ΄ λΆμμ ν μμ κ³Ό μ€λ₯κ° λ°μν μ μμ΅λλ€.
λ°±κ·ΈλΌμ΄λ μμ μ μ΄λ¬ν μ₯κΈ° μ€νμ μ€μνμ§ μμ μμ μ κΈ°λ³Έ μμ² μ²λ¦¬ νλ‘μΈμ€μ λΆλ¦¬νμ¬ μ°μν μ루μ μ μ 곡ν©λλ€. μ΄λ₯Ό ν΅ν΄ APIλ μμ μ΄ μμλμμμ νμΈνλ©΄μ μ¬μ©μμκ² μ μνκ² μλ΅ν μ μμΌλ©° μ€μ μμ μ λ°±κ·ΈλΌμ΄λμμ λΉλκΈ°μ μΌλ‘ μνλ©λλ€.
FastAPIμ λ΄μ₯ λ°±κ·ΈλΌμ΄λ μμ
FastAPIλ κ°λ¨ν μ¬μ© μ¬λ‘λ₯Ό μν΄ μΈλΆ μ’ μμ± μμ΄ λ°±κ·ΈλΌμ΄λμμ μμ μ μ€νν μ μλ κ°λ¨ν λ©μ»€λμ¦μ μ 곡ν©λλ€. `BackgroundTasks` ν΄λμ€λ μ΄λ¬ν μ©λλ‘ μ€κ³λμμ΅λλ€.
`BackgroundTasks` μλ λ°©μ
μμ²μ΄ FastAPI μ ν리μΌμ΄μ μ λ€μ΄μ€λ©΄ `BackgroundTasks`μ μΈμ€ν΄μ€λ₯Ό κ²½λ‘ μμ ν¨μμ μ£Όμ ν μ μμ΅λλ€. μ΄ κ°μ²΄λ μλ΅μ΄ ν΄λΌμ΄μΈνΈλ‘ μ μ‘λ ν μ€νλμ΄μΌ νλ ν¨μλ₯Ό 보κ΄νλ 컨ν μ΄λ μν μ ν©λλ€.
λ€μμ κΈ°λ³Έ ꡬ쑰μ λλ€.
from fastapi import FastAPI, BackgroundTasks
app = FastAPI()
def send_email_background(email: str, message: str):
# Simulate sending an email
print(f"Simulating sending email to {email} with message: {message}")
# In a real application, this would involve SMTP or an email service API.
# For global applications, consider time zone aware sending and retry mechanisms.
@app.post("/send-notification/{email}")
async def send_notification(email: str, message: str, background_tasks: BackgroundTasks):
background_tasks.add_task(send_email_background, email, message)
return {"message": "Notification sent in background"}
μ΄ μμ μμλ λ€μκ³Ό κ°μ΅λλ€.
- μμ μ λν λ‘μ§μ ν¬ν¨νλ `send_email_background` ν¨μλ₯Ό μ μν©λλ€.
- `BackgroundTasks`λ₯Ό κ²½λ‘ μμ ν¨μ `send_notification`μ λ§€κ° λ³μλ‘ μ£Όμ ν©λλ€.
- `background_tasks.add_task()`λ₯Ό μ¬μ©νμ¬ `send_email_background`κ° μ€νλλλ‘ μμ½ν©λλ€. μμ ν¨μμ λν μΈμλ `add_task`μ λν νμ μΈμλ‘ μ λ¬λ©λλ€.
- APIλ ν΄λΌμ΄μΈνΈμ μ¦μ μ±κ³΅ λ©μμ§λ₯Ό λ°ννκ³ μ΄λ©μΌ μ μ‘ νλ‘μΈμ€λ λ°±κ·ΈλΌμ΄λμμ κ³μλ©λλ€.
`BackgroundTasks`μ λν μ£Όμ κ³ λ € μ¬ν
- νλ‘μΈμ€ μλͺ μ£ΌκΈ°: `BackgroundTasks`λ₯Ό ν΅ν΄ μΆκ°λ μμ μ FastAPI μ ν리μΌμ΄μ κ³Ό λμΌν Python νλ‘μΈμ€ λ΄μμ μ€νλ©λλ€. μ ν리μΌμ΄μ νλ‘μΈμ€κ° λ€μ μμλκ±°λ μΆ©λνλ©΄ 보λ₯ μ€μΈ λ°±κ·ΈλΌμ΄λ μμ μ΄ μμ€λ©λλ€.
- μ§μμ± μμ: μλ²κ° λ€μ΄λ κ²½μ° μ€ν¨ν μμ μ λ€μ μλνκ±°λ μ μ§νκΈ° μν κΈ°λ³Έ μ 곡 λ©μ»€λμ¦μ΄ μμ΅λλ€.
- 볡μ‘ν μν¬νλ‘μ λν μ ν μ¬ν: κ°λ¨νκ³ μ¦μ μ€νλλ μμ μλ νλ₯νμ§λ§ λΆμ° μμ€ν , μν κ΄λ¦¬ λλ 보μ₯λ μ€νκ³Ό κ΄λ ¨λ 볡μ‘ν μν¬νλ‘μλ `BackgroundTasks`κ° μΆ©λΆνμ§ μμ μ μμ΅λλ€.
- μ€λ₯ μ²λ¦¬: λ°±κ·ΈλΌμ΄λ μμ λ΄μ μ€λ₯λ κΈ°λ³Έμ μΌλ‘ κΈ°λ‘λμ§λ§ ν΄λΌμ΄μΈνΈλ‘ λ€μ μ νλκ±°λ μ΄κΈ° μλ΅μ μν₯μ μ£Όμ§ μμ΅λλ€. μμ ν¨μ λ΄μμ λͺ μμ μΈ μ€λ₯ μ²λ¦¬κ° νμν©λλ€.
μ΄λ¬ν μ ν μ¬νμλ λΆκ΅¬νκ³ FastAPIμ κΈ°λ³Έ `BackgroundTasks`λ νΉν μ¦κ°μ μΈ μμ μλ£κ° μ€μνμ§ μμ μ ν리μΌμ΄μ μμ λ§μ μΌλ°μ μΈ μλ리μ€μμ μλ΅μ±μ κ°μ νκΈ° μν κ°λ ₯ν λꡬμ λλ€.
μΈλΆ μμ νλ₯Ό μ¬μ©ν΄μΌ νλ κ²½μ°
νΉν κΉλ€λ‘μ΄ κΈλ‘λ² νκ²½μμ λ³΄λ€ κ°λ ₯νκ³ νμ₯ κ°λ₯νλ©° 볡μλ ₯μ΄ λ°μ΄λ λ°±κ·ΈλΌμ΄λ μμ μ²λ¦¬λ₯Ό μν΄μλ μ μ© μμ ν μμ€ν κ³Ό ν΅ν©νλ κ²μ΄ μ’μ΅λλ€. μ΄λ¬ν μμ€ν μ λ€μκ³Ό κ°μ κΈ°λ₯μ μ 곡ν©λλ€.
- λΆλ¦¬: μμ μ μΉ μλ²μ μμ ν λ 립μ μΈ λ³λμ μμ μ νλ‘μΈμ€μμ μ²λ¦¬λ©λλ€.
- μ§μμ±: μλ² λ€μ μμ λλ μ€ν¨ μμλ μμ μ μ μ§ν μ μλλ‘ λ°μ΄ν°λ² μ΄μ€ λλ λ©μμ§ λΈλ‘컀μ μμ μ μ μ₯ν μ μμ΅λλ€.
- μ¬μλ λ° μ€λ₯ μ²λ¦¬: μ€ν¨ν μμ μ μλμΌλ‘ μ¬μλνκ³ μ€λ₯λ₯Ό μ²λ¦¬νκΈ° μν μ κ΅ν λ©μ»€λμ¦.
- νμ₯μ±: μμ λ‘λ μ¦κ°λ₯Ό μ²λ¦¬νκΈ° μν΄ μΉ μλ²μ λ 립μ μΌλ‘ μμ μ νλ‘μΈμ€ μλ₯Ό νμ₯ν μ μμ΅λλ€.
- λͺ¨λν°λ§ λ° κ΄λ¦¬: μμ νλ₯Ό λͺ¨λν°λ§νκ³ , μμ μνλ₯Ό κ²μ¬νκ³ , μμ μλ₯Ό κ΄λ¦¬νλ λꡬ.
- λΆμ° μμ€ν : μμ μ΄ λ€λ₯Έ μλΉμ€μμ λλ λ€λ₯Έ μμ€ν μμ μ²λ¦¬λμ΄μΌ νλ λ§μ΄ν¬λ‘μλΉμ€ μν€ν μ²μ νμμ μ λλ€.
λͺ κ°μ§ μΈκΈ° μλ μμ ν λΌμ΄λΈλ¬λ¦¬κ° Python λ° FastAPIμ μννκ² ν΅ν©λ©λλ€.
1. Celery
Celeryλ Pythonμμ κ°μ₯ μΈκΈ° μκ³ κ°λ ₯ν λΆμ° μμ ν μμ€ν μ€ νλμ λλ€. λ§€μ° μ μ°νλ©° RabbitMQ, Redis λλ Amazon SQSμ κ°μ λ€μν λ©μμ§ λΈλ‘컀μ ν¨κ» μ¬μ©ν μ μμ΅λλ€.
FastAPIλ‘ Celery μ€μ
νμ 쑰건:
- Celery λ° λ©μμ§ λΈλ‘컀(μ: Redis)λ₯Ό μ€μΉν©λλ€.
pip install celery[redis]
1. Celery μ ν리μΌμ΄μ νμΌ(μ: `celery_worker.py`)μ λ§λλλ€.
from celery import Celery
# Configure Celery
# Use a broker URL, e.g., Redis running on localhost
celery_app = Celery(
'tasks',
broker='redis://localhost:6379/0',
backend='redis://localhost:6379/0'
)
# Optional: Define tasks here or import them from other modules
@celery_app.task
def process_data(data: dict):
# Simulate a long-running data processing task.
# In a global app, consider multi-language support, internationalization (i18n),
# and localization (l10n) for any text processing.
print(f"Processing data: {data}")
# For internationalization, ensure data formats (dates, numbers) are handled correctly.
return f"Processed: {data}"
2. FastAPI μ ν리μΌμ΄μ κ³Ό ν΅ν©ν©λλ€(`main.py`):
from fastapi import FastAPI
from celery_worker import celery_app # Import your Celery app
app = FastAPI()
@app.post("/process-data/")
async def start_data_processing(data: dict):
# Send the task to Celery
task = celery_app.send_task('tasks.process_data', args=[data])
return {"message": "Data processing started", "task_id": task.id}
# Endpoint to check task status (optional but recommended)
@app.get("/task-status/{task_id}")
async def get_task_status(task_id: str):
task_result = celery_app.AsyncResult(task_id)
return {
"task_id": task_id,
"status": str(task_result.status),
"result": task_result.result if task_result.ready() else None
}
3. Celery μμ μλ₯Ό μ€νν©λλ€.
λ³λμ ν°λ―Έλμμ νλ‘μ νΈ λλ ν°λ¦¬λ‘ μ΄λνμ¬ λ€μμ μ€νν©λλ€.
celery -A celery_worker worker --loglevel=info
4. FastAPI μ ν리μΌμ΄μ μ μ€νν©λλ€.
uvicorn main:app --reload
Celeryλ₯Ό μ¬μ©ν κΈλ‘λ² κ³ λ € μ¬ν:
- λΈλ‘컀 μ ν: κΈλ‘λ² μ ν리μΌμ΄μ μ κ²½μ° λ¨μΌ μ€ν¨ μ§μ μ λ°©μ§νκΈ° μν΄ Amazon SQS λλ κ΄λ¦¬ν Kafka μλΉμ€μ κ°μ΄ κ°μ©μ±μ΄ λκ³ λΆμ°λ λ©μμ§ λΈλ‘컀λ₯Ό κ³ λ €νμμμ€.
- μκ°λ: μμ μ μμ½νκ±°λ μκ°μ λ―Όκ°ν λ°μ΄ν°λ₯Ό μ²λ¦¬ν λ μ ν리μΌμ΄μ λ° μμ μμμ μκ°λλ₯Ό μΌκ΄λκ² μ²λ¦¬ν΄μΌ ν©λλ€. UTCλ₯Ό νμ€μΌλ‘ μ¬μ©νμμμ€.
- κ΅μ ν(i18n) λ° νμ§ν(l10n): λ°±κ·ΈλΌμ΄λ μμ μ μ½ν μΈ (μ΄λ©μΌ, λ³΄κ³ μ) μμ±μ΄ ν¬ν¨λ κ²½μ° λ€μν μ§μμ λ§κ² νμ§νλμλμ§ νμΈνμμμ€.
- λμμ± λ° μ²λ¦¬λ: λ€μν μ§μμμ μμλλ λ‘λ λ° μ¬μ© κ°λ₯ν μλ² λ¦¬μμ€λ₯Ό κΈ°λ°μΌλ‘ Celery μμ μ μμ ν΄λΉ λμμ± μ€μ μ μ‘°μ ν©λλ€.
2. Redis Queue (RQ)
RQλ Redisλ₯Ό κΈ°λ°μΌλ‘ ꡬμΆλ Celeryμ λ κ°λ¨ν λμμ λλ€. λ μμ νλ‘μ νΈμ μ νΈλκ±°λ λ 볡μ‘ν μ€μ μ΄ νμν κ²½μ°κ° λ§μ΅λλ€.
FastAPIλ‘ RQ μ€μ
νμ 쑰건:
- RQ λ° Redisλ₯Ό μ€μΉν©λλ€.
pip install rq
1. μμ νμΌ(μ: `tasks.py`)μ λ§λλλ€.
import time
def send_international_email(recipient: str, subject: str, body: str):
# Simulate sending an email, considering international mail servers and delivery times.
print(f"Sending email to {recipient} with subject: {subject}")
time.sleep(5) # Simulate work
print(f"Email sent to {recipient}.")
return f"Email sent to {recipient}"
2. FastAPI μ ν리μΌμ΄μ κ³Ό ν΅ν©ν©λλ€(`main.py`):
from fastapi import FastAPI
from redis import Redis
from rq import Queue
app = FastAPI()
# Connect to Redis
redis_conn = Redis(host='localhost', port=6379, db=0)
# Create an RQ queue
q = Queue(connection=redis_conn)
@app.post("/send-email-rq/")
def send_email_rq(
recipient: str,
subject: str,
body: str
):
# Enqueue the task
task = q.enqueue(send_international_email, recipient, subject, body)
return {"message": "Email scheduled for sending", "task_id": task.id}
# Endpoint to check task status (optional)
@app.get("/task-status-rq/{task_id}")
def get_task_status_rq(task_id: str):
job = q.fetch_job(task_id)
if job:
return {
"task_id": task_id,
"status": job.get_status(),
"result": job.result if job.is_finished else None
}
return {"message": "Task not found"}
3. RQ μμ μλ₯Ό μ€νν©λλ€.
λ³λμ ν°λ―Έλμμ:
python -m rq worker default
4. FastAPI μ ν리μΌμ΄μ μ μ€νν©λλ€.
uvicorn main:app --reload
RQλ₯Ό μ¬μ©ν κΈλ‘λ² κ³ λ € μ¬ν:
- Redis κ°μ©μ±: μ ν리μΌμ΄μ μ΄ μ§§μ λκΈ° μκ° μꡬ μ¬νμΌλ‘ κΈλ‘λ² μ²μ€μκ² μλΉμ€λ₯Ό μ 곡νλ κ²½μ° Redis μΈμ€ν΄μ€κ° κ°μ©μ±μ΄ λκ³ μ μ¬μ μΌλ‘ μ§λ¦¬μ μΌλ‘ λΆμ°λμ΄ μλμ§ νμΈνμμμ€. κ΄λ¦¬ν Redis μλΉμ€κ° μ’μ μ΅μ μ λλ€.
- νμ₯μ± μ ν: RQκ° λ κ°λ¨νμ§λ§ λΆμ° νκ²½μ μν Celeryμ κ΄λ²μν ν΄λ§μ λΉν΄ νμ₯μ λ λ§μ μλ λ Έλ ₯μ΄ νμν μ μμ΅λλ€.
3. κΈ°ν μμ ν(μ: Dramatiq, KafkaJS/Faustλ₯Ό μ¬μ©νλ Apache Kafka)
νΉμ μꡬ μ¬νμ λ°λΌ λ€λ₯Έ μμ ν μ루μ μ΄ λ μ ν©ν μ μμ΅λλ€.
- Dramatiq: Celeryμ λ κ°λ¨νκ³ μ΅μ λμμΌλ‘ Redis λ° RabbitMQλ μ§μν©λλ€.
- Apache Kafka: λμ μ²λ¦¬λ, λ΄κ²°ν¨μ± λ° μ€νΈλ¦Ό μ²λ¦¬ κΈ°λ₯μ΄ νμν μ ν리μΌμ΄μ μ κ²½μ° Kafkaλ₯Ό λ°±κ·ΈλΌμ΄λ μμ μ λν λ©μμ§ λΈλ‘μ»€λ‘ μ¬μ©ν μ μμ΅λλ€. Faustμ κ°μ λΌμ΄λΈλ¬λ¦¬λ Kafkaλ₯Ό κΈ°λ°μΌλ‘ Python μ€νΈλ¦Ό μ²λ¦¬ νλ μμν¬λ₯Ό μ 곡ν©λλ€. μ΄λ νΉν λκ·λͺ¨ λ°μ΄ν° μ€νΈλ¦Όμ΄ μλ κΈλ‘λ² μ ν리μΌμ΄μ κ³Ό κ΄λ ¨μ΄ μμ΅λλ€.
κΈλ‘λ² λ°±κ·ΈλΌμ΄λ μμ μν¬νλ‘ μ€κ³
κΈλ‘λ² λμμ μν λ°±κ·ΈλΌμ΄λ μμ μμ€ν μ ꡬμΆν λλ κΈ°λ³Έ ꡬν μΈμλ λͺ κ°μ§ μμλ₯Ό μ μ€νκ² κ³ λ €ν΄μΌ ν©λλ€.
1. μ§λ¦¬μ λΆν¬ λ° λκΈ° μκ°
μ μΈκ³ μ¬μ©μκ° λ€μν μμΉμμ APIμ μνΈ μμ©ν©λλ€. μΉ μλ²μ μμ μμ λ°°μΉλ μ±λ₯μ ν° μν₯μ λ―ΈμΉ μ μμ΅λλ€.
- μμ μ λ°°μΉ: λ°μ΄ν° μμ€ λλ μνΈ μμ©νλ μλΉμ€μ μ§λ¦¬μ μΌλ‘ λ κ°κΉμ΄ μ§μμ μμ μλ₯Ό λ°°ν¬νλ κ²μ κ³ λ €νμμμ€. μλ₯Ό λ€μ΄, μμ μ μ λ½ λ°μ΄ν° μΌν°μ λ°μ΄ν° μ²λ¦¬κ° ν¬ν¨λ κ²½μ° μ λ½μ μμ μλ₯Ό λ°°μΉνλ©΄ λκΈ° μκ°μ μ€μΌ μ μμ΅λλ€.
- λ©μμ§ λΈλ‘컀 μμΉ: λ©μμ§ λΈλ‘μ»€κ° λͺ¨λ μΉ μλ² λ° μμ μ μΈμ€ν΄μ€μμ μ§§μ λκΈ° μκ°μΌλ‘ μ‘μΈμ€ν μ μλμ§ νμΈνμμμ€. AWS SQS, Google Cloud Pub/Sub λλ Azure Service Busμ κ°μ κ΄λ¦¬ν ν΄λΌμ°λ μλΉμ€λ κΈλ‘λ² λ°°ν¬ μ΅μ μ μ 곡ν©λλ€.
- μ μ μμ°μ© CDN: λ°±κ·ΈλΌμ΄λ μμ μμ μ¬μ©μκ° λ€μ΄λ‘λνλ λ³΄κ³ μ λλ νμΌμ μμ±νλ κ²½μ° CDN(μ½ν μΈ μ μ‘ λ€νΈμν¬)μ μ¬μ©νμ¬ μ΄λ¬ν μμ°μ μ μΈκ³μ μΌλ‘ μ 곡ν©λλ€.
2. μκ°λ λ° μμ½
μκ°μ μ¬λ°λ₯΄κ² μ²λ¦¬νλ κ²μ κΈλ‘λ² μ ν리μΌμ΄μ μ λ§€μ° μ€μν©λλ€. λ°±κ·ΈλΌμ΄λ μμ μ νΉμ μκ°μ μμ½νκ±°λ λ€λ₯Έ μκ°μ λ°μνλ μ΄λ²€νΈλ₯Ό κΈ°λ°μΌλ‘ νΈλ¦¬κ±°ν΄μΌ ν μ μμ΅λλ€.
- UTC μ¬μ©: νμ νμμ€ν¬νλ₯Ό νμ μΈκ³μ(UTC)λ‘ μ μ₯νκ³ μ²λ¦¬ν©λλ€. νμ λͺ©μ μΌλ‘λ§ νμ§ μκ°λλ‘ λ³ννμμμ€.
- μμ½λ μμ : νΉμ μκ°μ μμ μ μ€νν΄μΌ νλ κ²½μ°(μ: λ§€μΌ λ³΄κ³ μ) μμ½ λ©μ»€λμ¦μ΄ λ€μν μκ°λλ₯Ό κ³ λ €νλμ§ νμΈνμμμ€. μλ₯Ό λ€μ΄ Celery Beatλ νΉμ μκ°μ μ μΈκ³μ μΌλ‘ μμ μ μ€ννλλ‘ κ΅¬μ±ν μ μλ cronκ³Ό μ μ¬ν μμ½μ μ§μν©λλ€.
- μ΄λ²€νΈ κΈ°λ° νΈλ¦¬κ±°: μ΄λ²€νΈ κΈ°λ° μμ μ κ²½μ° μ΄λ²€νΈ νμμ€ν¬νκ° UTCλ‘ νμ€νλμλμ§ νμΈνμμμ€.
3. κ΅μ ν(i18n) λ° νμ§ν(l10n)
λ°±κ·ΈλΌμ΄λ μμ μμ μ΄λ©μΌ, μλ¦Ό λλ λ³΄κ³ μμ κ°μ μ¬μ©μμκ² νμλλ μ½ν μΈ λ₯Ό μμ±νλ κ²½μ° νμ§νν΄μΌ ν©λλ€.
- i18n λΌμ΄λΈλ¬λ¦¬: Python i18n λΌμ΄λΈλ¬λ¦¬(μ: `gettext`, `babel`)λ₯Ό μ¬μ©νμ¬ λ²μμ κ΄λ¦¬ν©λλ€.
- λ‘μΊ κ΄λ¦¬: λ°±κ·ΈλΌμ΄λ μμ μ²λ¦¬μμ μ¬μ©μμ μ νΈ λ‘μΊμ κ²°μ νμ¬ μ¬λ°λ₯Έ μΈμ΄μ νμμΌλ‘ μ½ν μΈ λ₯Ό μμ±ν μ μλμ§ νμΈνμμμ€.
- νμ μ§μ : λ μ§, μκ°, μ«μ λ° ν΅ν νμμ μ§μμ λ°λΌ ν¬κ² λ€λ¦ λλ€. κ°λ ₯ν νμ μ§μ λ‘μ§μ ꡬνν©λλ€.
4. μ€λ₯ μ²λ¦¬ λ° μ¬μλ
λ€νΈμν¬ λΆμμ , μΌμμ μΈ μλΉμ€ μ€λ₯ λλ λ°μ΄ν° λΆμΌμΉλ‘ μΈν΄ μμ μ΄ μ€ν¨ν μ μμ΅λλ€. 볡μλ ₯μ΄ λ°μ΄λ μμ€ν μ κΈλ‘λ² μ΄μμ λ§€μ° μ€μν©λλ€.
- λ©±λ±μ±: κ°λ₯ν κ²½μ° μμ μ λ©±λ±μ±μΌλ‘ μ€κ³ν©λλ€. μ¦, μ΄κΈ° μ€ν μ΄ν κ²°κ³Όλ₯Ό λ³κ²½νμ§ μκ³ μ¬λ¬ λ² μ€νν μ μμ΅λλ€. μ΄λ μμ ν μ¬μλμ λ§€μ° μ€μν©λλ€.
- μ§μ λ°±μ€ν: μΌμμ μΈ λ¬Έμ λ₯Ό κ²ͺκ³ μλ μλΉμ€λ₯Ό μλνμ§ μλλ‘ μ¬μλμ λν΄ μ§μ λ°±μ€νλ₯Ό ꡬνν©λλ€.
- λ°λλ ν° ν(DLQ): μ€μν μμ μ κ²½μ° λ°λ³΅μ μΌλ‘ μ€ν¨νλ μμ μ μΊ‘μ²νλλ‘ DLQλ₯Ό ꡬμ±νμ¬ κΈ°λ³Έ μμ νλ₯Ό μ°¨λ¨νμ§ μκ³ μλ κ²μ¬ λ° ν΄κ²°μ΄ κ°λ₯νλλ‘ ν©λλ€.
5. 보μ
λ°±κ·ΈλΌμ΄λ μμ μ μ’ μ’ μ€μν λ°μ΄ν° λλ μΈλΆ μλΉμ€μ μνΈ μμ©ν©λλ€.
- μΈμ¦ λ° κΆν λΆμ¬: λ°±κ·ΈλΌμ΄λμμ μ€νλλ μμ μ νμν μ격 μ¦λͺ λ° κΆνμ΄ μλμ§ νμΈνλ νμν κ² μ΄μμ νμΈνμ§ λ§μμμ€.
- λ°μ΄ν° μνΈν: μμ μμ μ€μν λ°μ΄ν°λ₯Ό μ²λ¦¬νλ κ²½μ° μ μ‘ μ€(μλΉμ€μ μμ μ κ°) λ° μ μ₯ μ(λ©μμ§ λΈλ‘컀 λλ λ°μ΄ν°λ² μ΄μ€) λͺ¨λ μνΈνλμλμ§ νμΈνμμμ€.
- μνΈ κ΄λ¦¬: λ°±κ·ΈλΌμ΄λ μμ μκ° νμν API ν€, λ°μ΄ν°λ² μ΄μ€ μ격 μ¦λͺ λ° κΈ°ν μνΈλ₯Ό κ΄λ¦¬νκΈ° μν 보μ λ°©λ²μ μ¬μ©ν©λλ€.
6. λͺ¨λν°λ§ λ° κ΄μ°° κ°λ₯μ±
λ°±κ·ΈλΌμ΄λ μμ μμ€ν μ μνμ μ±λ₯μ μ΄ν΄νλ κ²μ λ¬Έμ ν΄κ²° λ° μ΅μ νμ νμμ μ λλ€.
- λ‘κΉ : νμμ€ν¬ν, μμ ID λ° κ΄λ ¨ 컨ν μ€νΈλ₯Ό ν¬ν¨νμ¬ μμ λ΄μμ ν¬κ΄μ μΈ λ‘κΉ μ ꡬνν©λλ€.
- λ©νΈλ¦: μμ μ€ν μκ°, μ±κ³΅λ₯ , μ€ν¨μ¨, ν κΈΈμ΄ λ° μμ μ νμ©λ₯ μ λν λ©νΈλ¦μ μμ§ν©λλ€.
- μΆμ : λΆμ° μΆμ μ μ¬λ¬ μλΉμ€μμ μμ² λ° μμ μ νλ¦μ μκ°ννλ λ° λμμ΄ λμ΄ λ³λͺ© νμκ³Ό μ€λ₯λ₯Ό μ½κ² μλ³ν μ μμ΅λλ€. Jaeger λλ OpenTelemetryμ κ°μ λꡬλ₯Ό ν΅ν©ν μ μμ΅λλ€.
FastAPIμμ λ°±κ·ΈλΌμ΄λ μμ μ ꡬννκΈ° μν λͺ¨λ² μ¬λ‘
FastAPIμ κΈ°λ³Έ μ 곡 `BackgroundTasks`λ₯Ό μ¬μ©νλ μΈλΆ μμ νλ₯Ό μ¬μ©νλ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄μμμ€.
- μμ μ μ§μ€μ μ΄κ³ μμμ μΌλ‘ μ μ§: κ° λ°±κ·ΈλΌμ΄λ μμ μ λ¨μΌνκ³ μ μ μλ μμ μ μννλ κ²μ΄ μ’μ΅λλ€. μ΄λ κ² νλ©΄ ν μ€νΈ, λλ²κ·Έ λ° μ¬μλκ° λ μ¬μμ§λλ€.
- μ€ν¨λ₯Ό μν μ€κ³: μμ μ΄ μ€ν¨ν κ²μ΄λΌκ³ κ°μ ν©λλ€. κ°λ ₯ν μ€λ₯ μ²λ¦¬, λ‘κΉ λ° μ¬μλ λ©μ»€λμ¦μ ꡬνν©λλ€.
- μ’ μμ± μ΅μν: λ°±κ·ΈλΌμ΄λ μμ μλ μμ μ ν¨μ¨μ μΌλ‘ μννλ λ° νμν μ’ μμ±λ§ κ°μ ΈμΌ ν©λλ€.
- λ°μ΄ν° μ§λ ¬ν μ΅μ ν: APIμ μμ μ κ°μ 볡μ‘ν λ°μ΄ν°λ₯Ό μ λ¬νλ κ²½μ° ν¨μ¨μ μΈ μ§λ ¬ν νμ(μ: JSON, Protocol Buffers)μ μ νν©λλ€.
- μ² μ ν ν μ€νΈ: μμ ν¨μλ₯Ό λ¨μ ν μ€νΈνκ³ FastAPI μ±κ³Ό μμ ν κ°μ ν΅μ μ ν΅ν© ν μ€νΈν©λλ€.
- ν λͺ¨λν°λ§: μμ ν, μμ μ μ±λ₯ λ° μ€λ₯μ¨μ μνλ₯Ό μ κΈ°μ μΌλ‘ νμΈν©λλ€.
- κ°λ₯ν κ²½μ° μμ λ΄μμ λΉλκΈ° μμ μ¬μ©: λ°±κ·ΈλΌμ΄λ μμ μμ I/O νΈμΆ(μ: λ€λ₯Έ API λλ λ°μ΄ν°λ² μ΄μ€)μ ν΄μΌ νλ κ²½μ° μ νν μμ ν μ€νκΈ°κ° μ΄λ₯Ό μ§μνλ κ²½μ° μμ ν¨μ λ΄μμ λΉλκΈ° λΌμ΄λΈλ¬λ¦¬(`httpx`λ₯Ό μ¬μ©νμ¬ HTTP μμ² λλ `asyncpg`λ₯Ό μ¬μ©νμ¬ PostgreSQL)λ₯Ό μ¬μ©ν©λλ€(μ: μμ½μ `countdown` λλ `eta`λ₯Ό μ¬μ©νλ `apply_async`κ° μλ Celery λλ `gevent`/`eventlet` μμ μ). μ΄λ κ² νλ©΄ ν¨μ¨μ±μ λμ± λμΌ μ μμ΅λλ€.
μμ μλ리μ€: κΈλ‘λ² μ μ μκ±°λ μ£Όλ¬Έ μ²λ¦¬
μ μΈκ³ μ¬μ©μκ° μλ μ μ μκ±°λ νλ«νΌμ κ³ λ €ν΄ λ³΄κ² μ΅λλ€. μ¬μ©μκ° μ£Όλ¬Ένλ©΄ λ€μκ³Ό κ°μ μ¬λ¬ μμ μ΄ λ°μν΄μΌ ν©λλ€.
- κ³ κ°μκ² μλ¦Ό: μ£Όλ¬Έ νμΈ μ΄λ©μΌμ 보λ λλ€.
- μ¬κ³ μ λ°μ΄νΈ: μ¬κ³ μμ€μ μ€μ λλ€.
- κ²°μ μ²λ¦¬: κ²°μ κ²μ΄νΈμ¨μ΄μ μνΈ μμ©ν©λλ€.
- λ°°μ‘ λΆμμ μλ¦Ό: λ°°μ‘ λͺ μΈμλ₯Ό λ§λλλ€.
μ΄λ¬ν μμ μ΄ λͺ¨λ λκΈ°μ μ΄λ©΄ κ³ κ°μ νμΈμ μν΄ μ€λ«λμ κΈ°λ€λ €μΌ νκ³ μ ν리μΌμ΄μ μ΄ λ‘λ μ μλ΅νμ§ μμ μ μμ΅λλ€.
λ°±κ·ΈλΌμ΄λ μμ μ¬μ©:
- μ£Όλ¬ΈνκΈ° μν μ¬μ©μμ μμ²μ FastAPIμμ μ²λ¦¬λ©λλ€.
- FastAPIλ μ¦μ μ¬μ©μμκ² μ£Όλ¬Έ νμΈ μλ΅μ λ°νν©λλ€. "μ£Όλ¬Έμ΄ μ μλμμΌλ©° μ²λ¦¬ μ€μ λλ€. κ³§ μ΄λ©μΌμ λ°μΌμ€ μ μμ΅λλ€."
- λ€μ μμ μ΄ κ°λ ₯ν μμ ν(μ: Celery)μ μΆκ°λ©λλ€.
- `send_order_confirmation_email(order_details)`: μ΄ μμ μ κ³ κ°μ λ‘μΊμ κ³ λ €νμ¬ μ΄λ©μΌ ν νλ¦Ώμ λν i18nμ μ²λ¦¬ν©λλ€.
- `update_inventory_service(order_items)`: μ μ¬μ μΌλ‘ λ€λ₯Έ μ§μ μ°½κ³ μμ μ¬κ³ λ₯Ό μ λ°μ΄νΈνκΈ° μν λ§μ΄ν¬λ‘μλΉμ€ νΈμΆμ λλ€.
- `process_payment_gateway(payment_details)`: μ§μ μλν¬μΈνΈκ° μμ μ μλ κ²°μ μ²λ¦¬κΈ°μ μνΈ μμ©ν©λλ€. μ΄ μμ μλ κ°λ ₯ν μ€λ₯ μ²λ¦¬ λ° μ¬μλ λ‘μ§μ΄ νμν©λλ€.
- `generate_shipping_manifest(order_id, shipping_address)`: μ΄ μμ μ λμ κ΅κ°μ κ΄μΈ κ·μ μ κ³ λ €νμ¬ λ°°μ‘ λΆμμ λν λ°μ΄ν°λ₯Ό μ€λΉν©λλ€.
μ΄ λΉλκΈ°μ μ κ·Ό λ°©μμ κ³ κ°μκ² λΉ λ₯Έ μλ΅μ 보μ₯νκ³ κΈ°λ³Έ APIκ° μ°¨λ¨λλ κ²μ λ°©μ§νλ©° νΌν¬ κΈλ‘λ² μΌν μμ¦μλ μ£Όλ¬Έμ νμ₯ κ°λ₯νκ³ λ³΅μλ ₯ μκ² μ²λ¦¬ν μ μλλ‘ ν©λλ€.
κ²°λ‘
λΉλκΈ° μμ μ€νμ νΉν κΈλ‘λ² λμμ μλΉμ€νλ κ³ μ±λ₯μ νμ₯ κ°λ₯νκ³ μ¬μ©μ μΉνμ μΈ μ ν리μΌμ΄μ μ ꡬμΆνλ λ° μμ΄ μ΄μμ λλ€. λ°±κ·ΈλΌμ΄λ μμ μ μ°μν ν΅ν©μ κ°μΆ Python FastAPIλ κ²¬κ³ ν κΈ°λ°μ μ 곡ν©λλ€. κ°λ¨νκ³ μ¦μ μ€νλλ μμ μ κ²½μ° FastAPIμ κΈ°λ³Έ μ 곡 `BackgroundTasks` ν΄λμ€κ° νλ₯ν μμμ μ λλ€.
κ·Έλ¬λ 볡μλ ₯, μ§μμ±, μ¬μλ, λΆμ° μ²λ¦¬ λ° κ°λ ₯ν λͺ¨λν°λ§κ³Ό κ°μ κ³ κΈ κΈ°λ₯μ μꡬνλ κΉλ€λ‘κ³ λ―Έμ ν¬λ¦¬ν°μ»¬ν μ ν리μΌμ΄μ μ κ²½μ° Celery λλ RQμ κ°μ κ°λ ₯ν μμ ν μμ€ν κ³Ό ν΅ν©νλ κ²μ΄ νμμ μ λλ€. μ§λ¦¬μ λΆν¬, μκ°λ, κ΅μ ν λ° κ°λ ₯ν μ€λ₯ μ²λ¦¬μ κ°μ κΈλ‘λ² μμλ₯Ό μ μ€νκ² κ³ λ €νμ¬ λ°±κ·ΈλΌμ΄λ μμ μ νμ©νμ¬ μ μΈκ³ μ¬μ©μλ₯Ό μν μ§μ μΌλ‘ μ±λ₯μ΄ λ°μ΄λκ³ μμ μ μΈ μΉ μλΉμ€λ₯Ό ꡬμΆν μ μμ΅λλ€.
FastAPIμμ λ°±κ·ΈλΌμ΄λ μμ μ λ§μ€ν°νλ κ²μ λ¨μν κΈ°μ μ ꡬνμ κ΄ν κ²μ΄ μλλΌ μλ΅μ±μ΄ λ°μ΄λκ³ μμ μ μ΄λ©° κΈλ‘λ² μ¬μ©μ κΈ°λ°μ λ€μν μꡬ μ¬νμ μΆ©μ‘±νλλ‘ νμ₯ν μ μλ μμ€ν μ μ€κ³νλ κ²μ λλ€.