k6 Load Testing Tool 1/5
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 ครับ
ติดตั้ง Brew
install หน้านี้เลย ตามด้วยการกำหนด PATH
จากนั้นติดตั้ง k6 ด้วย brew install k6
ติดตั้ง Docker
install docker หน้านี้เลย
จากนั้นใช้ k6 ด้วย docker pull grafana/k6
Running k6 local tests
เริ่มจากการสร้างไฟล์ script.js หรือจะตั้งชื่ออื่นก็ได้
ถ้าเป็น Brew ก็ว่า k6 new
ถ้าเป็น docker ก็ว่า
docker run — rm -i -v $PWD:/app -w /app grafana/k6 new
เราจะได้ default file ชื่อ script.js
แต่ถ้าอยากได้ JavaScript scripting ชื่ออื่น ก็ตั้งเองได้เลย
ถ้าเป็น Brew ก็ว่า k6 new test.js
ผลลัพธ์
ถ้าเป็น Docker ก็ว่า
docker run — rm -i -v $PWD:/app -w /app grafana/k6 new loadtest.js
ผลลัพธ์
การรัน script
ถ้าเป็น Brew ก็ว่า k6 run script.js
ผลลัพธ์
ถ้าเป็น Docker ก็ว่า
docker run — rm -i grafana/k6 run — <script.js
ผลลัพธ์
In script detail
มาทำความเข้าใจ script ที่เครื่องมือนี้ generated ให้เรา เริ่มจากเปิดไฟล์ script.js แล้วลบทุกบรรทัด จากนั้นเริ่มเขียนใหม่ ดังนี้
ทุก test จะต้องมี default function อารมรณ์เดียวกับ main function ในภาษาอื่นๆ
export default function() {}
รันแล้วดูผลลัพธ์
จากผลลัพธ์ตีความได้ว่า
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)
}
ผลลัพธ์
ลองให้ 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)
}
ผลลัพธ์
อีกความสามารถที่โชว์คือการเพิ่มและลดจำนวน 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 ตามลักษระนี้ได้นั่นเอง
ผลลัพธ์
พอสัมผัสได้รู้จัก k6 กันแล้ว ค่อยๆไป ตอนถัดไปเรามาเข้าเนื้อหาโหลดแต่ละรูปแบบกันนะครับ