Load Test (with K6) - 3sam5oh/webtoon-search-service GitHub Wiki

K6 ๊ณต์‹๋ฌธ์„œ


Note

์‹œ์Šคํ…œ์˜ ์„ฑ๋Šฅ์„ ํ‰๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์Šคํ…œ์˜ ์‘๋‹ต ์‹œ๊ฐ„, ์ฒ˜๋ฆฌ๋Ÿ‰, ์•ˆ์ •์„ฑ ๋“ฑ์„ ์ธก์ •ํ•˜๋Š” ํ…Œ์ŠคํŠธ


Load Test ์ˆ˜ํ–‰ ์ด์œ 

ํ•ญ๋ชฉ ์„ค๋ช…
์„ฑ๋Šฅ ๋ณ‘๋ชฉ์  ํŒŒ์•… ์‹œ์Šคํ…œ์ด ๋†’์€ ํŠธ๋ž˜ํ”ฝ์—์„œ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ผ์œผํ‚ค๋Š” ๋ถ€๋ถ„์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค
์•ˆ์ •์„ฑ ํ™•์ธ ํŠน์ • ๋ถ€ํ•˜ ์กฐ๊ฑด์—์„œ ์‹œ์Šคํ…œ์ด ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค
์šฉ๋Ÿ‰ ๊ณ„ํš ์‹œ์Šคํ…œ์ด ์˜ˆ์ƒ๋˜๋Š” ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์–ผ๋งˆ๋‚˜ ์ž˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์˜ˆ์ธกํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณ„ํšํ•  ์ˆ˜ ์žˆ๋‹ค
์„ฑ๋Šฅ ๊ธฐ์ค€ ๊ฒ€์ฆ ์‹œ์Šคํ…œ์ด ์„ค์ •๋œ ์„ฑ๋Šฅ ๊ธฐ์ค€์„ ์ถฉ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

Load Test์˜ ์ฃผ์š” ๊ฐœ๋…

ํ•ญ๋ชฉ ์„ค๋ช…
Virtual Users (๊ฐ€์ƒ ์‚ฌ์šฉ์ž) ํ…Œ์ŠคํŠธ ์‹œ ์‹ค์ œ ์‚ฌ์šฉ์ž์ฒ˜๋Ÿผ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•˜๋Š” ์‹œ๋ฎฌ๋ ˆ์ด์…˜๋œ ์‚ฌ์šฉ์ž๋“ค
Transactions (ํŠธ๋žœ์žญ์…˜) ์‚ฌ์šฉ์ž ์ž‘์—…์„ ์ •์˜ํ•˜๋Š” ๋‹จ์œ„๋กœ, ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์€ ํ•˜๋‚˜ ์ด์ƒ์˜ HTTP ์š”์ฒญ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค
Throughput (์ฒ˜๋ฆฌ๋Ÿ‰) ์‹œ์Šคํ…œ์ด ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์š”์ฒญ์˜ ์ˆ˜
Response Time (์‘๋‹ต ์‹œ๊ฐ„) ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›๊ธฐ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„
Concurrent Users (๋™์‹œ ์‚ฌ์šฉ์ž) ๋™์‹œ์— ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•˜์—ฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ˆ˜

Load Test ์ง„ํ–‰ ์‹œ ํ™•์ธํ•ด์•ผ ํ•  ์ฃผ์š” ์‚ฌํ•ญ

  1. ์‘๋‹ต ์‹œ๊ฐ„(Response Time):
- ๊ฐ ์š”์ฒญ์˜ ์‘๋‹ต ์‹œ๊ฐ„
- ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„
- ์ตœ๋Œ€ ๋ฐ ์ตœ์†Œ ์‘๋‹ต ์‹œ๊ฐ„
  1. ์ฒ˜๋ฆฌ๋Ÿ‰(Throughput):
- ์ดˆ๋‹น ์ฒ˜๋ฆฌ๋˜๋Š” ์š”์ฒญ ์ˆ˜
- ์ดˆ๋‹น ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ ์–‘
  1. ์—๋Ÿฌ ๋น„์œจ(Error Rate):
- ์š”์ฒญ ์ค‘ ์‹คํŒจํ•œ ๋น„์œจ
- ์—๋Ÿฌ ์ฝ”๋“œ ๋ฐ ์›์ธ ๋ถ„์„
  1. ์ž์› ์‚ฌ์šฉ๋ฅ (Resource Utilization):
- CPU ์‚ฌ์šฉ๋ฅ 
- ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
- ๋””์Šคํฌ I/O
- ๋„คํŠธ์›Œํฌ ๋Œ€์—ญํญ ์‚ฌ์šฉ๋Ÿ‰
  1. ๋™์‹œ ์‚ฌ์šฉ์ž ์ˆ˜(Concurrent Users):
- ํ…Œ์ŠคํŠธ ์ค‘ ๋™์‹œ์— ํ™œ๋™ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ˆ˜
- ์‚ฌ์šฉ์ž ์ฆ๊ฐ€์— ๋”ฐ๋ฅธ ์„ฑ๋Šฅ ๋ณ€ํ™”
  1. ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ(Bottlenecks):
- ์‘๋‹ต ์‹œ๊ฐ„์ด ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•˜๋Š” ์ง€์ 
- ์ž์› ์‚ฌ์šฉ๋Ÿ‰์ด ๊ธ‰์ฆํ•˜๋Š” ์ง€์ 

์ฃผ์˜์‚ฌํ•ญ

ํ•ญ๋ชฉ ์„ค๋ช…
ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ์ •์˜ ์‹ค์ œ ์‚ฌ์šฉ ํŒจํ„ด์„ ๋ฐ˜์˜ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ํ˜„์‹ค์„ฑ ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰
๋ฐ์ดํ„ฐ ์ค€๋น„ ํ…Œ์ŠคํŠธ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋Š” ์ถฉ๋ถ„ํžˆ ์ค€๋น„๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€
ํ™˜๊ฒฝ ์ผ์น˜ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์ด ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ๊ณผ ์ตœ๋Œ€ํ•œ ์œ ์‚ฌํ•ด์•ผ ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค
๋ชจ๋‹ˆํ„ฐ๋ง ํ…Œ์ŠคํŠธ ๋™์•ˆ ์‹œ์Šคํ…œ์˜ ์ž์› ์‚ฌ์šฉ๋Ÿ‰์„ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์—ฌ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ํŒŒ์•…
๋‹จ๊ณ„์  ๋ถ€ํ•˜ ์ฆ๊ฐ€ ๋ถ€ํ•˜๋ฅผ ์ ์ง„์ ์œผ๋กœ ์ฆ๊ฐ€์‹œ์ผœ ์„ฑ๋Šฅ ํ•œ๊ณ„๋ฅผ ํŒŒ์•…

Load Test Types

chart-load-test-types-overview

ํ•ญ๋ชฉ ์„ค๋ช… VUs/์ฒ˜๋ฆฌ๋Ÿ‰ ๊ธฐ๊ฐ„ ์‹œ๊ธฐ
Smoke Test ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž‘๋™ํ•˜๋Š”์ง€, ์‹œ์Šคํ…œ์ด ์ตœ์†Œํ•œ์˜ ๋ถ€ํ•˜์—์„œ ์ ์ ˆํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๊ฒ€์ฆ ๋‚ฎ์Œ (2~20๋ช…) ์งง์Œ (30์ดˆ~3๋ถ„) ๊ด€๋ จ ์‹œ์Šคํ…œ ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ. ๊ธฐ๋Šฅ ๋กœ์ง, ๊ธฐ์ค€ ๋ฉ”ํŠธ๋ฆญ ๋ฐ ํŽธ์ฐจ๋ฅผ ํ™•์ธ
AverageLoad Test ์˜ˆ์ƒ๋˜๋Š” ์ •์ƒ ์กฐ๊ฑด์—์„œ ์‹œ์Šคํ…œ์˜ ์„ฑ๋Šฅ์„ ํ‰๊ฐ€ ํ‰๊ท  ์ค‘๊ฐ„ (5-60๋ถ„) ์‹œ์Šคํ…œ์ด ํ‰๊ท ์ ์ธ ์‚ฌ์šฉ์œผ๋กœ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฃผ ํ™•์ธ
Stress Test ๋ถ€ํ•˜๊ฐ€ ์˜ˆ์ƒ ํ‰๊ท ์„ ์ดˆ๊ณผํ•  ๋•Œ ์‹œ์Šคํ…œ์ด ํ•œ๊ณ„์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ‰๊ฐ€ ๋†’์Œ (ํ‰๊ท  ์ด์ƒ) ์ค‘๊ฐ„ (5-60๋ถ„) ์‹œ์Šคํ…œ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ‰๊ท  ์ด์ƒ์˜ ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
Soak Test ์žฅ๊ธฐ๊ฐ„์— ๊ฑธ์ณ ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ํ‰๊ฐ€ ํ‰๊ท  ๊ธธ๊ฒŒ (์˜ค๋žœ ์‹œ๊ฐ„) ์žฅ๊ธฐ๊ฐ„ ์—ฐ์† ์‚ฌ์šฉ ์‹œ ์‹œ์Šคํ…œ ์ ๊ฒ€์„ ์œ„ํ•ด ๋ณ€๊ฒฝํ•œ ํ›„
Spike Test ๊ฐ‘์ž‘์Šค๋Ÿฝ๊ณ  ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ ํ™œ๋™์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ์‹œ์Šคํ…œ์˜ ๋™์ž‘๊ณผ ์ƒ์กด์„ ๊ฒ€์ฆ ๋งค์šฐ ๋†’์Œ ์งง์Œ (๋ช‡ ๋ถ„) ์‹œ์Šคํ…œ์ด ์‹œ์ฆŒ๋ณ„ ์ด๋ฒคํŠธ์— ๋Œ€๋น„ํ•˜๊ฑฐ๋‚˜ ํŠธ๋ž˜ํ”ฝ์ด ์ž์ฃผ ํญ์ฃผํ•˜๋Š” ๊ฒฝ์šฐ
Breakpoint Test ์‹œ์Šคํ…œ์˜ ์šฉ๋Ÿ‰ ํ•œ๊ณ„๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์ ์ฐจ์ ์œผ๋กœ ๋ถ€ํ•˜๋ฅผ ์ฆ๊ฐ€ ์ค‘๋‹จ๋  ๋•Œ๊นŒ์ง€ ์ฆ๊ฐ€ ํ•„์š”ํ•œ ๊ธฐ๊ฐ„ ๋™์•ˆ ์‹œ์Šคํ…œ์˜ ์ƒํ•œ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋ช‡ ๋ฒˆ์ด๋‚˜

K6 ์‚ฌ์šฉ ์˜ˆ์‹œ

1. K6 ์„ค์น˜


2. script ์ž‘์„ฑ

test.js

import http from "k6/http";

const BASE_URL = __ENV.BASE_URL || "http://localhost:3333";

export default function () {
  let restrictions = {
    maxCaloriesPerSlice: 500,
    mustBeVegetarian: false,
    excludedIngredients: ["pepperoni"],
    excludedTools: ["knife"],
    maxNumberOfToppings: 6,
    minNumberOfToppings: 2,
  };
  let res = http.post(`${BASE_URL}/api/pizza`, JSON.stringify(restrictions), {
    headers: {
      "Content-Type": "application/json",
      "X-User-ID": 23423,
    },
  });
  console.log(`${res.json().pizza.name} (${res.json().pizza.ingredients.length} ingredients)`);
}

3. script ์‹คํ–‰

k6 run test.js

4. ๊ฒฐ๊ณผ ํ™•์ธ

          /\      |โ€พโ€พ| /โ€พโ€พ/   /โ€พโ€พ/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   โ€พโ€พ\  
   /          \   |  |\  \ |  (โ€พ)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0000] The Big Pugliese (5 ingredients)              source=console

     data_received..................: 686 B 483 B/s
     data_sent......................: 323 B 227 B/s
     http_req_blocked...............: avg=1.22ms   min=1.22ms   med=1.22ms   max=1.22ms   p(90)=1.22ms   p(95)=1.22ms  
     http_req_connecting............: avg=223ยตs    min=223ยตs    med=223ยตs    max=223ยตs    p(90)=223ยตs    p(95)=223ยตs   
     http_req_duration..............: avg=417.43ms min=417.43ms med=417.43ms max=417.43ms p(90)=417.43ms p(95)=417.43ms
       { expected_response:true }...: avg=417.43ms min=417.43ms med=417.43ms max=417.43ms p(90)=417.43ms p(95)=417.43ms
     http_req_failed................: 0.00% โœ“ 0        โœ— 1  
     http_req_receiving.............: avg=212ยตs    min=212ยตs    med=212ยตs    max=212ยตs    p(90)=212ยตs    p(95)=212ยตs   
     http_req_sending...............: avg=72ยตs     min=72ยตs     med=72ยตs     max=72ยตs     p(90)=72ยตs     p(95)=72ยตs    
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=417.15ms min=417.15ms med=417.15ms max=417.15ms p(90)=417.15ms p(95)=417.15ms
     http_reqs......................: 1     0.703775/s
     iteration_duration.............: avg=1.42s    min=1.42s    med=1.42s    max=1.42s    p(90)=1.42s    p(95)=1.42s   
     iterations.....................: 1     0.703775/s
     vus............................: 1     min=1      max=1
     vus_max........................: 1     min=1      max=1


running (00m01.4s), 0/1 VUs, 1 complete and 0 interrupted iterations
default โœ“ [======================================] 1 VUs  00m01.4s/10m0s  1/1 iters, 1 per VU

5. ์ธก์ • ํ•ญ๋ชฉ ๋ถ„์„

ํ•ญ๋ชฉ ์„ค๋ช…
http_reqs ์š”์ฒญ ์ˆ˜(์š”์ฒญ ๋น„์œจ)๋ฅผ ์ธก์ •
http_req_failed ์˜ค๋ฅ˜์œจ(์˜ค๋ฅ˜)์„ ์ธก์ •
http_req_duration ์‘๋‹ต ์‹œ๊ฐ„(๋Œ€๊ธฐ ์‹œ๊ฐ„)์„ ์ธก์ •
vus ๊ฐ€์ƒ ์‚ฌ์šฉ์ž ์ˆ˜(ํŠธ๋ž˜ํ”ฝ)๋ฅผ ์ธก์ •

๋“ฑ์˜ ์ง€ํ‘œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋” ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ๋ฉ”ํŠธ๋ฆญ ๊ด€๋ จ ๋ฌธ์„œ์—์„œ ํ™•์ธ




SLI, SLO, SLA

๊ด€๋ จ ๋ฌธ์„œ

Service Level Indicator (SLI, ์„œ๋น„์Šค ์ˆ˜์ค€ ์ฒ™๋„)

  • ํ”„๋กœ์ ํŠธ์— ๊ด€๋ จ๋œ ์‹ค์ œ ์ •๋ณด ํ•„์š”, ์–ด๋–ค ๊ฒƒ์„ ํ…Œ์ŠคํŠธ๋ฅผ ํ• ์ง€์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…์„ ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•  ๊ฒƒ ๊ฐ™์Œ

Service Level Object (SLO, ์„œ๋น„์Šค ์ˆ˜์ค€ ๋ชฉํ‘œ)

  • ํ”„๋กœ์ ํŠธ์— ๊ด€๋ จ๋œ ์‹ค์ œ ์ •๋ณด ํ•„์š”, SLI์™€ ๋งˆ์ฐฌ๊ฐ€์ง€

Service Level Agreements (SLA, ์„œ๋น„์Šค ์ˆ˜์ค€ ํ˜‘์•ฝ)

  • ํ”„๋กœ์ ํŠธ์— ๊ด€๋ จ๋œ ์‹ค์ œ ์ •๋ณด ํ•„์š” (ํฌ๊ฒŒ ๊ณ ๋ ค ์‚ฌํ•ญ์€ ์•„๋‹ ๊ฒƒ ๊ฐ™์Œ)
โš ๏ธ **GitHub.com Fallback** โš ๏ธ