공정하고 격리된 방식으로 웹 프레임워크를 벤치마크하는 방법 | Mahdi Shamlou

발행: (2026년 2월 22일 오전 05:39 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

여러분, 안녕하세요! 마흐디 샤몰루입니다 👋

온라인에서 웹 프레임워크를 비교하는 많은 글을 봤지만, 대부분 편향되었거나 오래됐거나 재현하기 어려웠습니다. 그래서 저는 모든 웹 프레임워크를 벤치마크할 수 있는 실용적인 방법을 공유하고자 합니다. 모든 것을 격리하고, 공정하며, 재현 가능하게 유지합니다.

우리는 격리를 위해 Docker를 사용하고, 부하 테스트를 위해 k6를 사용하며, 간단한 예시로 Python 프레임워크인 FastAPI와 Flask를 사용할 것입니다. 이 접근 방식은 Node.js, Go, Java, Rust 등 다른 어떤 언어에도 적용할 수 있습니다.

개요

웹 프레임워크 벤치마킹은 까다로울 수 있습니다. 결과에 영향을 주는 많은 요인이 있습니다:

  • CPU 및 메모리 가용성
  • 워커/스레드 수
  • 백그라운드 프로세스
  • 라우팅, 로깅, 데이터베이스, I/O

공정한 비교를 위해서는 다음이 필요합니다:

  • 고정된 CPU 및 메모리 제한이 있는 Docker 컨테이너
  • 각 프레임워크에서 동일한 라우트 또는 엔드포인트
  • k6(또는 유사 도구)를 사용한 제어된 부하 테스트
  • 이후 분석을 위한 결과 저장

프로젝트 구조

mkdir web_framework_benchmarks
cd web_framework_benchmarks
mkdir framework1 framework2 k6-tests results

framework1framework2을 비교하고 싶은 어떤 프레임워크로든 교체할 수 있습니다. 예시로 간단한 /hello 엔드포인트를 사용합니다.

FastAPI (Python)

# app.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
def hello():
    return {"message": "hello world"}

Flask (Python)

# app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/hello")
def hello():
    return jsonify({"message": "hello world"})

Node.js, Go, Java 등에서도 동일한 엔드포인트를 구현할 수 있으며, 기능은 동일하게 유지합니다. 필요에 따라 I/O‑집중 작업을 시뮬레이션하기 위해 슬립 라우트를 추가할 수도 있습니다.

Dockerfiles (공정한 비교)

FastAPI Dockerfile

# Dockerfile (FastAPI)
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install fastapi uvicorn gunicorn
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-w", "1", "-b", "0.0.0.0:8000", "app:app"]

Flask Dockerfile

# Dockerfile (Flask)
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask gunicorn
CMD ["gunicorn", "-w", "1", "-b", "0.0.0.0:8000", "app:app"]

✅ 이제 두 컨테이너 모두 동일한 워커 수와 동일한 CPU/메모리 제한을 가지고 있어 공정한 기준을 보장합니다.

k6를 이용한 부하 테스트

k6 스크립트 (JavaScript)

// k6-tests/framework1.js (or framework2.js)
import http from "k6/http";
import { sleep } from "k6";

export const options = {
  stages: [
    { duration: "30s", target: 50 },   // ramp‑up
    { duration: "1m", target: 200 },  // hold load
    { duration: "30s", target: 0 },   // ramp‑down
  ],
  thresholds: {
    "http_req_duration": ["p(95)<200"], // 95% of requests should be <200 ms
  },
};

export default function () {
  http.get("http://localhost:8001/hello");
  sleep(1);
}

테스트 실행

mkdir -p results
k6 run --out json=results/framework1.json k6-tests/framework1.js
k6 run --out json=results/framework2.json k6-tests/framework2.js

JSON 출력은 어떤 언어나 플로팅 도구로도 처리할 수 있습니다.

결과 분석

아래는 평균 지연 시간, 95번째 백분위 지연 시간, 요청 수, 실패율을 추출한 뒤 평균 응답 시간을 그래프로 표시하는 최소한의 Python 스크립트입니다.

# analyze.py
import json
import numpy as np
import matplotlib.pyplot as plt

files = {
    "Framework1": "results/framework1.json",
    "Framework2": "results/framework2.json"
}
summary = {}

for name, file in files.items():
    durations, fails, total = [], 0, 0
    with open(file) as f:
        for line in f:
            obj = json.loads(line)
            if obj.get("type") == "Point":
                metric = obj.get("metric")
                if metric == "http_req_duration":
                    durations.append(obj["data"]["value"])
                if metric == "http_req_failed":
                    fails += obj["data"]["value"]
                    total += 1
    if durations:
        summary[name] = {
            "avg": np.mean(durations),
            "p95": np.percentile(durations, 95),
            "requests": len(durations),
            "fail_rate": fails / total if total else 0,
        }

print(summary)

plt.bar(summary.keys(), [summary[n]["avg"] for n in summary])
plt.title("Average Response Time (ms)")
plt.ylabel("Milliseconds")
plt.show()

주요 요점

  • Docker 격리는 벤치마크를 재현 가능하게 합니다.
  • 워커 수 및 CPU 제한은 컨테이너 간에 일치해야 합니다.
  • 간단한 라우트는 Flask가 더 빠르게 보이게 할 수 있습니다; 속지 마세요.
  • Async/I/O가 많은 라우트는 FastAPI(또는 다른 async 프레임워크)의 강점을 보여줍니다.
  • 항상 실제 워크로드를 벤치마크하세요, 작은 예제만으로는 안 됩니다.

Repository

Dockerfile, k6 스크립트 및 분석 코드를 포함한 전체 예제는 다음에서 확인할 수 있습니다:

https://github.com/mahdi-shamlou/web_framework_benchmarks

레포지토리를 클론하고, Docker + k6 설정을 직접 실행해 보세요. FastAPI 및 Flask 예제를 탐색하거나, 비교를 위해 추가 프레임워크를 기여할 수 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »