k6 Load Testing Tool 1/5

Phai Panda
4 min readApr 29, 2024

--

Load Test คือกระบวนการการจำลองความต้องการของซอฟต์แวร์ แอปพลิเคชันหรือเว็บไซต์ เพื่อหาขีดจำกัดของระบบ (วัดประสิทธิภาพ)ให้แน่ใจว่าระบบจะยังคงมีเสถียรภาพกระทั่งถึงขีดจำกัดนั้น

ปกติสาย Java ก็มักจะคุ้นหูชื่อนี้ Apache JMeter แต่หนนี้เราจะพูดถึงอีกเครื่องมือหนึ่งที่มีชื่อว่า Grafana k6

k6

k6 ถูกออกแบบมาให้ใช้ทดสอบประสิทธิภาพและความน่าเชื่อถือของ APIs, microservices และ websites

k6 features

  • CLI tool มี API ให้นักพัฒนาใช้
  • เขียน load test script ด้วยภาษา JavaScript มาตราฐาน ES2015/ES6
  • มีฟังก์ชัน Checks และ Thresholds ใช้กำกับผลลัพธ์ที่คาดหวังจากการ load test (ทำให้เขียน script ได้ง่ายขึ้น)

Use cases

ผู้ใช้ k6 มักจะเป็น Developers, QA Engineers, SDETs (Software Developer Engineer in Test) และ SREs (Site Reliability Engineering)

  • Load testing: k6 ถูกปรับให้เหมาะสมเพื่อให้ใช้ทรัพยากรของเครื่องน้อยที่สุด ออกแบบให้สามารถทดสอบ high load (ใช้ spike, stress และ soak tests)
  • Browser testing: รองรับการทำ browser automation ด้วย k6 browser
  • Chaos and resilience testing: สามารถจำลองการส่งข้อมูลที่ซับซ้อนได้ รวมถึงข้อผิดพลาดประเภทต่างๆ (faults) ด้วย xk6-disruptor
  • Performance and synthetic monitoring: เขียน small load automate test โดยกำหนดเวลาที่ต้องการทดสอบ (schedule) ได้บ่อยครั้งตามต้องการ เพื่อตรวจสอบประสิทธิภาพและความพร้อมใช้งานของระบบ

What k6 does not

มีข้อเสียบางประการที่ต้องทราบนะ

  • Does not run natively in a browser: k6 จะไม่แสดงผลหน้าเว็บในลักษณะเดียวกับที่ browser ทั่วไปทำ เพราะ browser ทั่วไปสามารถใช้ทรัพยากรของระบบจำนวนมากได้ ในขณะที่ k6 ไม่ได้ถูกออกแบบให้ทำแบบนั้น (เหตุนี้มันจึงสามารถ run load จำนวนมากได้นั่นเอง) อย่างไรก็ตามหากต้องการ real browser, k6 ได้จัดเตรียม k6 browser ไว้ให้แล้ว
  • Does not run in NodeJS: ปกติแล้ว JavaScript ไม่เหมาะกับงานที่ต้องการ high performance, เพื่อให้เกิดประสิทธิภาพสูงสุด k6 จึงเขียนด้วยภาษา Go แล้วฝัง JavaScript Runtime มาให้, JavaScript scripting ตอบเรื่องความง่ายในการเขียนโค้ด แต่ถ้าต้องการ import npm modules หรือใช้ไลบรารี่ของ NodeJS ก็ต้องใช้วิธี bundle npm modules with webpack

Installation

ติดตั้งได้หมดไม่ว่าจะเป็น Linux, Mac และ Windows หน้านี้เลย

ในที่นี้เพราะผมใช้ Mac สนใจติดตั้ง 2 แบบเพื่อเป็นตัวอย่าง (เพื่อนๆเลือกอย่างหนึ่งอย่างใดก็ได้) คือผ่านเครื่องมือที่ชื่อ brew กับ docker ครับ

set brew to your OS PATH

brew install k6

brew install k6

docker install k6

docker pull grafana/k6

Running k6 local tests

brew create script.js

k6 new

docker create script.js

docker run — rm -i -v $PWD:/app -w /app grafana/k6 new

เราจะได้ default file ชื่อ script.js

แต่ถ้าอยากได้ JavaScript scripting ชื่ออื่น ก็ตั้งเองได้เลย เช่น

k6 new test.js สำหรับ brew

ผลลัพธ์

brew create test.js script

ถ้าเป็น docker ก็ว่า

docker run — rm -i -v $PWD:/app -w /app grafana/k6 new loadtest.js

ผลลัพธ์

docker create loadtest.js

brew run script.js

k6 run script.js

ผลลัพธ์

brew run script.js

docker run script.js

docker run — rm -i grafana/k6 run — <script.js

ผลลัพธ์

docker run script.js

In script detail

มาทำความเข้าใจ script ที่เครื่องมือนี้ generated ให้เรา เริ่มจากเปิดไฟล์ script.js แล้วลบทุกบรรทัด จากนั้นเริ่มเขียนใหม่ ดังนี้

ทุก test จะต้องมี default function อารมรณ์เดียวกับ main function ในภาษาอื่นๆ

export default function() {}

รันแล้วดูผลลัพธ์

no virtual user, no duration time

จากผลลัพธ์ตีความได้ว่า

execution

  • ถูก run ที่ local
  • ไฟล์ชื่อ script.js
  • ไม่มี output ใดๆ

scenarios

  • สำเร็จแล้ว 1 scenario
  • virtual users (VUs) ที่จะทำซ้ำ (multiple iterations)
  • ระยะเวลาทดสอบมากที่สุด (max duration) ที่ 10 นาที 30 วินาที

data received

  • จำนวน 0 Byte

data sent

  • จำนวน 0 Byte

iteration duration

  • ค่าเฉลี่ย (avg)

iterations

  • จำนวนวนซ้ำ

อ่านเพิ่มเติมเกี่ยวกับ Test lifecycle

virtual users (VUs) ง่ายๆคือจำลองจำนวนผู้ใช้งาน (user)

ทีนี้สมมติอยากรู้ว่าถ้ามี virtual user ใช้งาน (load) จำนวน 30 คน เป็นเวลา 10 วินาที ส่งคำขอไปยัง test.k6.io ล่ะ ? ก็จะเขียน config เป็น test options ดังนี้

import http from 'k6/http'
import { sleep } from 'k6'

export const options = {
vus: 30,
duration: '10s'
}

export default function () {
http.get('http://test.k6.io')
sleep(1)
}

ผลลัพธ์

30 virtual users, 10s duration time

ลองให้ virtual user ใช้งานจำนวน 10 คน เป็นเวลา 30 วินาทีล่ะ ?

import http from 'k6/http'
import { sleep } from 'k6'

export const options = {
vus: 10,
duration: '30s'
}

export default function () {
http.get('http://test.k6.io')
sleep(1)
}

ผลลัพธ์

10 virtual users, 30s duration time

อีกความสามารถที่โชว์คือการเพิ่มและลดจำนวน virtual users (Ramp VUs up and down) ตามช่วงเวลาที่กำหนดได้

import http from 'k6/http'
import { check, sleep } from 'k6'

export const options = {
stages: [
{ duration: '30s', target: 20 },
{ duration: '1m30s', target: 10 },
{ duration: '20s', target: 0 },
],
}

export default function () {
const res = http.get('http://test.k6.io')
check(res, { 'status was 200': (r) => r.status == 200 })
sleep(1)
}

options.stages ให้ค่าเป็น array ของ { duration, target } ตามตัวตัวอย่างกำหนดว่า 30 วินาทีแรกจะเพิ่มจำนวน virtual users เป็น 20 คน (เฉลี่ย-ค่อยๆเพิ่ม) ถัดจากนั้นอีก 1.30 นาทีจะลดจำนวน virtual users ให้เหลือ 10 คน (เมื่อเวลาผ่านไปครบ 2 นาทีก็จะเหลือ 10 คน) ถัดจากนั้นอีก 20 วินาทีจะลดให้เหลือ 0 คน (รวมแล้วใช้เวลาทดสอบ 2.20 นาที) แล้วจึงตรวจสอบว่าผลลัพธ์ (r) ที่ได้ทั้งหมดนั้นคือ 200 OK ใช่หรือไม่, ถ้า ใช่ ก็แสดงว่าระบบสามารถรองรับจำนวน load ตามลักษระนี้ได้นั่นเอง

ผลลัพธ์

Ramp VUs up and down

พอสัมผัสได้รู้จัก k6 กันแล้ว ค่อยๆไป ตอนถัดไปเรามาเข้าเนื้อหาโหลดแต่ละรูปแบบกันนะครับ

อ้างอิง

--

--