개념
k6를 배웠다면 절반은 안다
모듈 16(레슨 3)에서 k6로 가상 사용자를 만들고 p(95)와 실패율로
결과를 판단하는 법을 배웠다. Locust도 코드로 시나리오를 짠다는
철학은 똑같다. 가장 큰 차이는 언어다 — k6는 JavaScript,
Locust는 Python 이다.
이건 취향이 아니라 팀 구성의 문제다. 백엔드가 Django·FastAPI이거나 파이썬이 공용어인 조직에서는 부하 테스트만 JavaScript로 쓰는 게 진입 장벽이 된다. 사내 파이썬 유틸리티(테스트 데이터 생성기, 인증 모듈)를 그대로 import 해 쓸 수 있다는 것도 실무에서 큰 이점이다.
| k6 (모듈 16 레슨 3) | Locust | |
|---|---|---|
| 언어 | JavaScript | Python |
| 시나리오 단위 | export default function() 한 덩어리 | HttpUser 클래스 + 여러 개의 @task |
| 사용자 행동 분포 | 코드 안에서 직접 분기 처리 | @task(가중치)로 선언 |
| 실행 중 모니터링 | 종료 후 요약 출력이 기본 | 웹 UI에서 실시간 그래프 |
| 분산 실행 | 별도 구성/클라우드 서비스 | --master / --worker 옵션으로 기본 제공 |
기본 스크립트 구조
k6의 예시와 나란히 놓고 보면 대응 관계가 바로 보인다.
from locust import HttpUser, task, between
class ShopUser(HttpUser):
wait_time = between(1, 3) # k6의 sleep(1)에 해당
@task(8) # 8:2 = 80%가 이 행동
def view_products(self):
with self.client.get("/products", catch_response=True) as res:
if res.elapsed.total_seconds() > 0.5:
res.failure("응답이 500ms를 넘었다")
@task(2) # 20%가 이 행동
def purchase(self):
self.client.post("/orders", json={"productId": "P001", "quantity": 1})HttpUser를 상속한 클래스 하나가 가상 사용자 한 명의 인격 이다.
self.client는 요청을 보내는 객체이고, catch_response=True와
res.failure() 조합이 k6의 check() 자리를 대신한다.
task 가중치 — Locust가 특히 편한 지점
k6의 export default function()은 함수 하나가 전부라, "80%는 상품
조회, 20%는 구매"를 만들려면 함수 안에서 난수를 뽑아 직접 분기해야
한다. Locust는 그 분포를 @task(8), @task(2)처럼 선언만 하면
런타임이 알아서 섞어준다.
부하 테스트의 목적은 "현실과 닮은 트래픽"을 재현하는 것이다. 실제 서비스에서 모든 사용자가 결제만 반복하지는 않는다 — 조회가 압도적으로 많고 구매는 소수다. 그 비율이 코드에 드러나면 시나리오를 리뷰하는 개발자도 "이 부하가 우리 서비스와 닮았는지"를 판단할 수 있다.
실시간 웹 UI와 지표 대응
locust -f locustfile.py 로 실행하면 http://localhost:8089에 웹
화면이 뜬다. 사용자 수와 초당 증가율(spawn rate)을 입력하고 시작하면
실행되는 동안 RPS·응답 시간·실패율 그래프가 실시간으로 그려진다.
k6가 끝난 뒤 요약을 읽는 방식이라면, Locust는 무너지는 순간을 눈으로
보는 방식에 가깝다. 이름만 다를 뿐 읽어야 할 지표는 모듈 16과 같다.
| k6 (모듈 16 레슨 3) | Locust 웹 UI | 의미 |
|---|---|---|
http_req_duration avg | Average (ms) | 평균 응답 시간 — 왜곡되기 쉬움 |
http_req_duration p(95) | 95%ile (ms) | 요청의 95%가 이 시간 안에 끝남 |
http_req_failed | Fails / Fail ratio | 에러 응답 비율 |
vus | Users | 동시 가상 사용자 수 |
| — | RPS (Requests/s) | 초당 처리 요청 수 |
"평균의 함정"도 그대로다. Average가 200ms인데 95%ile이 1.8초라면, 20명 중 1명은 거의 2초를 기다리고 있다는 뜻이다.
분산 실행 — 부하가 커질 때
가상 사용자 수천 명을 만들려면 부하를 만드는 쪽(테스트를 돌리는 장비)이 먼저 한계에 부딪힌다. Locust는 마스터 하나가 여러 워커를 조율하는 구조를 옵션 두 개로 제공한다.
locust -f locustfile.py --master # 조율하는 쪽 — 웹 UI가 여기서 뜬다
# 실제로 부하를 만드는 쪽 — 여러 대에서 반복 실행
locust -f locustfile.py --worker --master-host=10.0.0.5결과는 마스터의 웹 UI 한 곳에 합쳐져 보인다. 파이썬 환경만 있으면 서버를 늘리는 것만으로 부하를 늘릴 수 있다.
실무에서 왜 필요한가
성능 테스트 도구는 회사마다 다르게 굳어 있다. k6·JMeter만 알고 있으면 "우리 팀은 Locust 씁니다"라는 한마디에 멈추게 된다.
더 중요한 건 도구를 넘나드는 판단력이다. 세 도구를 겪어보면 "무엇이 더 좋은가"가 아니라 팀의 언어, 필요한 부하 규모, 결과를 볼 사람이 누구인가 로 도구를 고르게 된다. 기획자와 함께 그래프를 보며 한계를 확인해야 한다면 Locust의 실시간 UI가, CI에서 매 배포마다 자동으로 돌려야 한다면 k6가 맞다.