
νμ¬ μ§ννκ³ μλ νλ‘μ νΈμμ μ΅κ·Ό λΆν ν μ€νΈλ₯Ό λ΄λΉνκ² λμμ΅λλ€. ν μ€νΈλ₯Ό μν λꡬλ μ¬λ¬ κ°μ§κ° μμ§λ§ μ ν¬λ λΉ λ₯΄κ³ κ°λ¨νκ² μ¬μ©ν μ μλ Locustλ₯Ό μ¬μ©νκΈ°λ‘ νμ΅λλ€.
μκ°λ³΄λ€ Locust μ¬μ© μ¬λ‘κ° λ§μ§ μμμ, μ΄ κ³Όμ μμ κ²ͺμλ κ³Όμ λ€κ³Ό λ¬Έμ λ€μ μ λ¦¬ν΄ λ³΄λ €κ³ ν©λλ€.
κ°λ¨ν μ¬μ©λ²
Locustλ Python μ½λλ₯Ό μμ±ν μ μλ€λ©΄ κ°λ¨νκ² μ¬μ©ν μ μμ΅λλ€.
Locustμμ μ€μν νμΌμ ν¬κ² 2κ°μ§μ λλ€.
locust.conf: ν μ€νΈ νκ²½μ λν μ€μ νμΌμ λλ€.locustfile.py: ν μ€νΈ μ½λλ₯Ό μμ±νλ νμΌμ λλ€.
λ¨Όμ locust.conf νμΌμ λ€μκ³Ό κ°μ ννλ‘ μμ±ν©λλ€.
(μ£Όμμ μ€μ μ¬μ©ν λλ μ§μ°λ©΄ λ©λλ€.)
locustfile = locustfile.py # μ€νν νμΌ
headless = true # ν€λλ¦¬μ€ λͺ¨λ μ¬μ© (μΉ μΈν°νμ΄μ€ μμ)
expect-workers = 10 # μ컀 μ
users = 10 # μ΅λ λμ μ¬μ©μ μ
spawn-rate = 2 # μ΄λΉ μμ±λλ μ¬μ©μ μ
run-time = 5m # ν
μ€νΈ μ€ν μκ°
loglevel=INFO
# html = "output/sample.html"
# csv = "output/sample.csv"
# logfile = "output/sample.log"
host = "https://www.example.com"
# host = "http://app.sample-namespace.svc.cluster.local:8000"
λ€λ₯Έ μ€μ μ μν©μ λ°λΌ μμ λ‘κ² λ³κ²½νλ©΄ λκ³ , μ€μν λΆλΆμ host λΆλΆμ
λλ€.
μ΄ λΆλΆμλ ν
μ€νΈλ₯Ό μ§νν μλ²μ URLμ μ
λ ₯ν©λλ€.
μΈλΆμμ μλ²μ μ κ·Όν μ μλ μν©μ΄λΌλ©΄, μ κ·Όν μ μλ URLμ μ
λ ₯νλ©΄ λ©λλ€.
λ§μ½ κ·Έλ μ§ μλ€λ©΄ λ΄λΆμμ μ κ·Ό κ°λ₯ν κ°μ μ€μ ν΄μΌ ν©λλ€.
λ€μμΌλ‘, locustfile.py νμΌμλ ν
μ€νΈ μ½λλ₯Ό μμ±ν©λλ€.
from locust import HttpUser, between, task
class TestApi(HttpUser):
wait_time = between(1, 2)
@task
def test_api(self):
self.client.get("/hello")
μμ£Ό κ°λ¨νκ² μμ±ν μμμ λλ€. μ§κΈμ λ¨μ GET μμ²μ΄μ§λ§, νλΌλ―Έν°λ₯Ό μΆκ°νκ±°λ νμΌμ μ λ‘λνκ³ , μΆκ° λ‘μ§μ μμ±νκ±°λ λ‘κ·Έλ₯Ό μΆκ°ν μλ μμ΅λλ€.
wait_time λΆλΆμ μ¬μ©μκ° μμ²μ 보λ΄λ μκ° κ°κ²©μ μλ―Έν©λλ€.
μμμμλ 1~2μ΄ μ¬μ΄μ 무μμ κ°κ²©μ κ°μ§λλ‘ μ€μ ν κ²μ
λλ€.
λΆν ν μ€νΈμμ κ²ͺμ λ¬Έμ λ€
μμμ μμ±ν κ²λ§ 보면 Locust μ¬μ©λ²μ κ°λ¨ν©λλ€.
νμ§λ§ μ€μ λ‘ μ μ©ν λλ λͺ κ°μ§ λ¬Έμ κ° μμμ΅λλ€.
λ΄λΆ νμλ§μμ ν μ€νΈνκΈ°
μ κ° ν
μ€νΈν΄μΌ νλ APIλ 격리λ Kubernetes νκ²½μ ꡬμ±λμ΄ μμμ΅λλ€.
λΉμ°ν λ΄λΆλ§μμλ§ APIμ μ κ·Όν μ μμκ³ , λν ν΄λ¬μ€ν° μΈλΆμμλ κ°λ° νκ²½μ ꡬμ±ν μ μμμ΅λλ€.
μ΄ μ‘°κ±΄μμ ν μ€νΈλ₯Ό μ§ννκΈ° μν΄ Locust νκ²½ μ 체λ₯Ό μ΄λ―Έμ§λ‘ λ§λ€κ³ , κ·Έ μ΄λ―Έμ§λ₯Ό Podλ‘ λ°°ν¬ν΄ ν μ€νΈλ₯Ό μ§ννμ΅λλ€. 컨ν μ΄λ λ΄λΆμμλ Kubernetes μλΉμ€μ ν¬νΈλ₯Ό ν΅ν΄ νΈμΆμ΄ κ°λ₯νκ³ , κ·Έ μΈμλ λΉμ·ν λ°©μμΌλ‘ ν μ€νΈλ₯Ό μ§ννμ΅λλ€.
μνλ κ²°κ³Όλ₯Ό νμΌλ‘ μ μ₯νκΈ°
Locustλ κΈ°λ³Έμ μΌλ‘ CSVμ HTML νμμΌλ‘ κ²°κ³Όλ₯Ό μ μ₯ν©λλ€.
νμ§λ§ μ΄ νμΌλ€μ μλ΅ μκ°κ³Ό μ±κ³΅λ₯ μ λλ§ νμνκ³ μκ³ , μΆκ°λ‘ μνλ μ λ³΄κ° μλ€λ©΄ μΆκ° μμ
μ΄ νμν©λλ€.
λν, μ΄ ν
μ€νΈ νμΌμ μ
λ§λλ‘ μμ ν μ μλ λ°©λ²μ΄ λ§λ
μΉ μμμ΅λλ€.

μ¬λ¬ λ°©λ©΄μΌλ‘ μ‘°μ¬ν κ²°κ³Ό, Locustμ Event hooksλ₯Ό μ¬μ©νλ©΄ κ°λ₯νλ€λ κ²μ μκ² λμμ΅λλ€.
λ€λ§ 곡μ μμ μ λ¬λ¦¬ μ€μ λ‘λ CSV νμΌμ λ°λ‘ μ μ₯ν΄μΌ νκ³ ,
μ€κ°κ°μ΄λ λΆμμ λ±μ μ 보λ κ³μ°ν΄μΌ νμ΅λλ€.
κ·Έλμ μ μμΌλ‘ 리μ€νΈ λ³μλ₯Ό μ μΈνκ³ , μμ²μ΄ μλ£λ λλ§λ€ λ°μ΄ν°λ₯Ό μΆκ°ν λ€μ
ν
μ€νΈ μ’
λ£ μ΄λ²€νΈμμ μ΅μ’
νμΌμ μ μ₯νλ λ°©μμΌλ‘ ꡬννμ΅λλ€.
곡μ μμ μμλ μ μ λ³μλ₯Ό μ¬μ©νκ³ , μ΄ μ λμ λ‘μ§μ΄ λΆν ν
μ€νΈμ ν° μν₯μ λ―ΈμΉμ§λ μμμ΅λλ€.
μμ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
from typing import Generator
from locust import HttpUser, task, between, events
from locust.runners import MasterRunner
from datetime import datetime
import logging
# import csv
# import os
# import numpy as np
API_KEY = "------"
stats = []
class TestApi(HttpUser):
wait_time = between(1, 2)
@task
def test_api(self):
data = {
# ...
}
headers = {"content-type": "application/json", "API-KEY": API_KEY}
res = self.client.post(
"/foo/bar",
json=data,
headers=headers
)
# Add the data to the stats
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
if not isinstance(environment.runner, MasterRunner):
# CSV file processing
logging.info(f"ν
μ€νΈκ° μλ£λμμ΅λλ€.")
else:
logging.info("Cleaning up test data")
κ·Έ μΈ
- Locustλ μ€νΈλ¦¬λ° μλ΅μ 곡μμ μΌλ‘ μ§μνμ§ μμ΅λλ€. μ΄μλ₯Ό 보면 ν΄λΌμ΄μΈνΈλ₯Ό μ§μ μμ±νλΌκ³ λμ΄ μλλ°, μ μ κ²½μ° μΌλ° API νΈμΆλ‘ ν΄κ²°μ νμ΅λλ€. μ€νΈλ¦¬λ° ν μ€νΈκ° νμνλ€λ©΄, λ€λ₯Έ λꡬλ₯Ό μκ°ν΄μΌ ν μλ μμ κ² κ°μ΅λλ€.
- λΉμ°νμ§λ§ Locust λͺ λ Ήμ΄λ₯Ό ν΅ν΄μλ μ€μ κ°μ μ§μ ν΄ ν μ€νΈλ₯Ό μ§νν μ μμ΅λλ€. μ μ κ²½μ°μλ μ¬λ¬ 쑰건μμ ν μ€νΈλ₯Ό μ§νν΄μΌ νλλ°, λ΄λΆλ§μμλ μ½λ μμ μ΄ μ½μ§ μκΈ° λλ¬Έμ 미리 μ€ν¬λ¦½νΈλ₯Ό μμ±ν΄ λκ³ λͺ λ Ήμ΄λ₯Ό ν΅ν΄ ν μ€νΈ 쑰건μ μ§μ νλ λ°©μμΌλ‘ μμ μ μ§ννμ΅λλ€.
λ§μΉλ©°
λμ보면 μ§κΈκΉμ§ ν
μ€νΈλ€μ΄ ν
μ€νΈλ₯Ό ν΄ λ³Έ μ μ΄ λ§μ§ μμλ κ² κ°μ΅λλ€. κ·Έλμ λ μ λλ‘ νκ³ μΆμ λ§μλ μμκ³ μ.
ν
μ€νΈ λ°©λ²μ μ 립νκΈ° μν΄μ μ λ λ§μ μνμ°©μ€λ₯Ό κ±°μ³€μ§λ§, API μ체μμ μκ°μ΄λ λ°μ΄ν°λ₯Ό μ»κΈ° μν μ€μ λ νμνκ³ , νμλ€μ΄ κ΄λ ¨ μμ
μ μ§μν΄ μ£Όμμ΅λλ€.
λν λ°©λ²λ λ°©λ²μ΄μ§λ§, λ€λ₯Έ νλ‘μ νΈμμλ λΉμ·ν λ°©λ²μΌλ‘ λΆν ν
μ€νΈλ₯Ό μ§νν μ μλλ‘ κΈ°μ€μ μ νκ³ , μ 리νλ κ²μ΄ μ½μ§ μμλ κ² κ°μ΅λλ€.
ν
μ€νΈλ₯Ό μννλ κ³Όμ μ΄ μννμ§λ μμμ§λ§, κΈ°ν λ΄μ μ λ§λ¬΄λ¦¬ν μ μμμ΅λλ€.
μμΌλ‘λ ν
μ€νΈλ₯Ό ν¬ν¨ν΄ λ§μ μμ
μ μ§ννκ² λ ν
λ°, μ΄ κ³Όμ μμ μ λλ νλ‘μΈμ€λ₯Ό λ§λ€μ΄ λκ° μ μλλ‘ νλ κ²μ΄ λͺ©νμ
λλ€.