วิธีวัดปริมาณงาน (Throughput) และขีดจำกัดการเชื่อมต่อพร้อมกันผ่านพร็อกซีด้วย k6 และ JMeter
บทความ
- บทนำ: ทำไมต้องรู้ขีดจำกัดล่วงหน้า แทนที่จะรู้ตอนรันงานใหญ่
- การเตรียมการเบื้องต้น: เครื่องมือ ข้อกำหนด และการเข้าถึง
- แนวคิดพื้นฐานในภาษาง่าย ๆ
- ขั้นตอนที่ 1: เตรียมเป้าหมายการทดสอบและข้อมูลพร็อกซี
- ขั้นตอนที่ 2: เข้าใจวิธีการทดสอบโหลดที่ถูกต้อง
- ขั้นตอนที่ 3: k6 - สคริปต์สำเร็จรูปพร้อมพร็อกซีและขั้นโหลด
- ขั้นตอนที่ 4: jmeter - สคริปต์เดียวกันพร้อมการตั้งค่าพร็อกซีในแผนการทดสอบ
- ขั้นตอนที่ 5: แยกแยะขีดจำกัดของพร็อกซี ขีดจำกัดของไคลเอนต์ และขีดจำกัดของเซิร์ฟเวอร์ - การตรวจสอบสามอย่าง
- ขั้นตอนที่ 6: ใช้ผลลัพธ์อย่างไร - เธรด พูล และเวลารันงาน
- ขั้นตอนที่ 7: จริยธรรมการทดสอบโหลดและโหมดที่อ่อนโยน
- การตรวจสอบผลลัพธ์: เช็กลิสต์ความพร้อม
- ข้อผิดพลาดทั่วไปและวิธีแก้ไข
- ความสามารถเพิ่มเติมและการปรับปรุง
- คำถามที่พบบ่อยเกี่ยวกับการวัดปริมาณงานผ่านพร็อกซี
- บทสรุป
การทำงานผ่านพร็อกซีมักจะเจอคำถามเดียวเสมอ: การเชื่อมต่อพร้อมกันจำนวนเท่าไหร่ที่ชุด "ไคลเอนต์ของคุณ - พร็อกซี - เซิร์ฟเวอร์ปลายทาง" จะรองรับได้จริงก่อนที่ความหน่วงจะพุ่งสูงขึ้นและข้อผิดพลาดจะเริ่มถาโถมเข้ามา คู่มือนี้จะสอนให้คุณวัดสิ่งเหล่านี้ล่วงหน้า ไม่ใช่วัดตอนที่ต้องรันงานใหญ่ ๆ ซึ่งความเสียหายอาจเป็นชั่วโมงของการหยุดทำงาน
บทนำ: ทำไมต้องรู้ขีดจำกัดล่วงหน้า แทนที่จะรู้ตอนรันงานใหญ่
ลองนึกภาพสถานการณ์ทั่วไป คุณกำลังรันงานเก็บข้อมูลสาธารณะจำนวนมากผ่านพร็อกซีพูล ทุกอย่างดูปกติดีในสองสามพันคำขอแรก แต่แล้วความหน่วงก็เริ่มเพิ่มขึ้น คำขอบางส่วนเริ่มล้มเหลวเพราะหมดเวลา และคุณไม่รู้ว่าปัญหามาจากโค้ดของคุณ พร็อกซี หรือเซิร์ฟเวอร์ปลายทาง ถึงตอนนั้นคุณก็เสียเวลาและอาจเสียข้อมูลไปแล้ว
วิธีที่ดีกว่าคือการทดสอบโหลดแบบควบคุมไว้ล่วงหน้าเพื่อหาจุดที่ประสิทธิภาพเริ่มเสื่อมลง แล้วคุณจะสามารถเลือกจำนวนเธรดที่ปลอดภัยและวางแผนเวลารันงานได้อย่างถูกต้อง
สิ่งที่ผู้อ่านจะได้รับจากคู่มือนี้
หลังจากอ่านจบ คุณจะสามารถทำสิ่งต่อไปนี้ได้ด้วยตัวเอง:
- สร้างสคริปต์ทดสอบโหลดที่ถูกต้องใน k6 และรันผ่านพร็อกซี
- ทำซ้ำสคริปต์เดียวกันใน JMeter พร้อมการตั้งค่าพร็อกซีในแผนการทดสอบ
- อ่านรายงาน: เข้าใจ RPS (คำขอต่อวินาที) ความหน่วงแบบเปอร์เซ็นไทล์ และอัตราข้อผิดพลาด
- แยกแยะขีดจำกัดของพร็อกซี ขีดจำกัดของไคลเอนต์ และขีดจำกัดของเซิร์ฟเวอร์ปลายทาง
- แปลงผลลัพธ์เป็นจำนวนเธรด ขนาดพูล และเวลาที่คาดว่าจะใช้ในการรันงาน
คู่มือนี้เหมาะสำหรับใคร
เนื้อหาออกแบบมาสำหรับวิศวกร นักวิเคราะห์ข้อมูล และนักพัฒนาระดับกลาง หากคุณเคยเขียนสคริปต์ JavaScript ง่าย ๆ หรือเคยรันโปรแกรมจาก命令行 คุณจะเข้าใจได้ไม่ยาก สำหรับมือใหม่ เราจะอธิบายทุกคำศัพท์ด้วยภาษาง่าย ๆ
สิ่งที่ต้องรู้มาก่อน
แค่ทักษะพื้นฐานก็พอ: เปิดเทอร์มินัล ติดตั้งโปรแกรม และแก้ไขไฟล์ข้อความ ความรู้เรื่อง HTTP ในระดับ "คำขอและการตอบกลับคืออะไร" จะเป็นข้อดี แต่ไม่จำเป็น
ใช้เวลานานแค่ไหน
การติดตั้งเครื่องมือจะใช้เวลาประมาณ 30-40 นาที คุณจะรันการทดสอบครั้งแรกใน k6 ได้ภายในหนึ่งชั่วโมง การทดสอบครบวงจรด้วย JMeter และการวิเคราะห์ผลจะใช้เวลาทำงานแบบไม่เร่งรีบประมาณ 3-4 ชั่วโมง
⚠️ ข้อควรระวัง: ตัวอย่างทั้งหมดในคู่มือนี้มีไว้สำหรับทดสอบระบบของคุณเองหรือทรัพยากรที่คุณได้รับอนุญาตให้ทดสอบโหลดอย่างชัดเจน การทดสอบโหลดบริการของผู้อื่นโดยไม่ได้รับความยินยอมเป็นสิ่งที่ไม่ควรทำ เราจะพูดถึงจริยธรรมนี้แยกต่างหากในตอนท้าย
การเตรียมการเบื้องต้น: เครื่องมือ ข้อกำหนด และการเข้าถึง
ก่อนที่จะวัด เราต้องเตรียมสภาพแวดล้อมการทำงานให้พร้อม นี่คือรายการสิ่งที่จำเป็นและวิธีติดตั้งแต่ละส่วนประกอบ
เครื่องมือและการเข้าถึงที่จำเป็น
- k6 - เครื่องมือทดสอบโหลดน้ำหนักเบา เขียนสคริปต์ด้วย JavaScript
- Apache JMeter - เครื่องมือคลาสสิกที่มีอินเทอร์เฟซกราฟิก ทำงานบน Java
- Java 17 หรือใหม่กว่า - จำเป็นสำหรับ JMeter
- การเข้าถึงพร็อกซี จาก Proxeon: ที่อยู่ พอร์ต ชื่อผู้ใช้ และรหัสผ่าน ข้อมูลนี้คุณจะได้รับจากบัญชีผู้ใช้ในบริการ
- เป้าหมายการทดสอบ - เซิร์ฟเวอร์ของคุณเองหรือทรัพยากรที่ได้รับอนุญาต
ข้อกำหนดของระบบ
เครื่องที่มี CPU 4 คอร์ และ RAM 8 GB ก็เพียงพอสำหรับการทำงานทั่วไป สำหรับโหลดสูง (ผู้ใช้เสมือนหลายพันคน) แนะนำให้ใช้ CPU 8 คอร์ และ RAM 16 GB ระบบปฏิบัติการ可以是 Windows, macOS หรือ Linux เนื่องจากเครื่องมือทั้งหมดรองรับหลายแพลตฟอร์ม
คำแนะนำ: ควรรันตัวสร้างโหลดบนเครื่องแยกต่างหากหรือเซิร์ฟเวอร์คลาวด์แยก เพื่อไม่ให้สับสนระหว่างโหลดที่เกิดจากแล็ปท็อปของคุณกับโหลดที่เกิดจากพร็อกซี
การติดตั้ง k6
- เปิดวิธีการติดตั้งอย่างเป็นทางการสำหรับระบบของคุณ: บน macOS ใช้ตัวจัดการแพ็กเกจ Homebrew ด้วยคำสั่ง brew install k6
- บน Windows ใช้ตัวจัดการแพ็กเกจ Chocolatey: choco install k6
- บน Linux ดาวน์โหลดแพ็กเกจจาก repository ของโปรเจกต์และติดตั้งผ่านตัวจัดการแพ็กเกจของระบบ
- ตรวจสอบการติดตั้งด้วยคำสั่ง k6 version - คุณจะเห็นหมายเลขเวอร์ชันตอบกลับมา
✅ การตรวจสอบ: หากคำสั่ง k6 version แสดงเวอร์ชันและไม่มีข้อผิดพลาด "command not found" แสดงว่าติดตั้งถูกต้องแล้ว
การติดตั้ง Java และ JMeter
- ติดตั้ง OpenJDK เวอร์ชัน 17 ขึ้นไป และตรวจสอบด้วยคำสั่ง java -version
- ดาวน์โหลดไฟล์บีบอัด Apache JMeter จากเว็บไซต์อย่างเป็นทางการในส่วนดาวน์โหลด
- แตกไฟล์ไปยังโฟลเดอร์ที่สะดวก เช่น ในโฮมไดเรกทอรี
- เข้าไปในโฟลเดอร์ย่อย bin ภายในโฟลเดอร์ JMeter ที่แตกแล้ว
- รันไฟล์ jmeter (บน Linux และ macOS) หรือ jmeter.bat (บน Windows)
- รอจนกระทั่งหน้าต่างกราฟิกปรากฏขึ้นพร้อมกับแผนผังแผนการทดสอบทางด้านซ้าย
✅ การตรวจสอบ: หากหน้าต่าง JMeter เปิดขึ้นพร้อมกับองค์ประกอบ "Test Plan" ในแผนผังด้านซ้าย แสดงว่าทุกอย่างพร้อมแล้ว
การสำรองข้อมูลและการเตรียมระบบทดสอบ
หากกำลังทดสอบบริการของคุณเอง ควรทำ snapshot หรือ backup ข้อมูลของระบบทดสอบไว้ล่วงหน้า โหลดไม่ควรทำให้โปรดักชันเสียหาย ถ้าเป็นไปได้ ใช้สำเนาสภาพแวดล้อมแทนเซิร์ฟเวอร์จริง
แนวคิดพื้นฐานในภาษาง่าย ๆ
เพื่อให้อ่านรายงานได้เข้าใจและไม่สับสนกับศัพท์เทคนิค มาทำความเข้าใจแนวคิดสำคัญกันก่อน
ปริมาณงานและ RPS
ปริมาณงาน (Throughput) คือปริมาณงานที่มีประโยชน์ที่ระบบทำได้ในหนึ่งหน่วยเวลา ในบริบทของ HTTP มักวัดเป็น RPS - จำนวนคำขอต่อวินาที ยิ่ง RPS สูงที่ความหน่วงที่ยอมรับได้ ยิ่งดี
ความหน่วงและเปอร์เซ็นไทล์
ความหน่วง (Latency) คือเวลาตั้งแต่ส่งคำขอจนกระทั่งได้รับคำตอบ ค่าเฉลี่ยเพียงอย่างเดียวอาจทำให้เข้าใจผิด เพราะคำขอที่ช้าผิดปกติจะถูกกลืนหายไปในค่าเฉลี่ย ดังนั้นจึงใช้ เปอร์เซ็นไทล์
เปอร์เซ็นไทล์ p95 หมายความว่า 95 เปอร์เซ็นต์ของคำขอเร็วกว่าค่านี้ และ 5 เปอร์เซ็นต์ช้ากว่า เปอร์เซ็นไทล์ p99 แสดงพฤติกรรมของคำขอที่ช้าที่สุด p95 และ p99 สะท้อนประสบการณ์จริงภายใต้โหลดได้ดีที่สุด
อัตราข้อผิดพลาดและจุดที่ประสิทธิภาพเสื่อม
อัตราข้อผิดพลาด คือเปอร์เซ็นต์ของคำขอที่จบลงไม่สำเร็จ: หมดเวลา ปฏิเสธการเชื่อมต่อ รหัสตอบกลับ 5xx จุดที่ประสิทธิภาพเสื่อม คือจุดที่การเพิ่มโหลดไม่ทำให้ RPS เพิ่มขึ้นอีก แต่ความหน่วงและข้อผิดพลาดกลับเพิ่มขึ้นอย่างรวดเร็ว นี่คือขีดจำกัดที่เรากำลังหา
การเชื่อมต่อพร้อมกันและผู้ใช้เสมือน
การเชื่อมต่อพร้อมกัน คือจำนวนคำขอที่ทำงานพร้อมกัน ใน k6 กำหนดผ่าน VU (virtual users – ผู้ใช้เสมือน) ใน JMeter กำหนดผ่านจำนวนเธรดใน Thread Group หนึ่ง VU หรือเธรดจะส่งคำขอตามลำดับ และหลาย ๆ ตัวรวมกันสร้างโหลดแบบขนาน
พร็อกซีในห่วงโซ่การทดสอบโหลด
พร็อกซีคือโหนดกลางที่คำขอของคุณไหลผ่าน พร็อกซีมีขีดจำกัดของตัวเองในเรื่องจำนวนการเชื่อมต่อพร้อมกันและปริมาณงาน เป้าหมายของเราคือการหาว่าระดับการเชื่อมต่อพร้อมกันเท่าไหร่ที่โหนดนี้กลายเป็นคอขวด
คำแนะนำ: จดสูตรของ Little ไว้: จำนวนเฉลี่ยของคำขอพร้อมกันประมาณเท่ากับ RPS คูณด้วยความหน่วงเฉลี่ยเป็นวินาที สูตรนี้ช่วยให้ประมาณการเชื่อมต่อพร้อมกันที่ต้องการได้อย่างรวดเร็ว
ขั้นตอนที่ 1: เตรียมเป้าหมายการทดสอบและข้อมูลพร็อกซี
เป้าหมายของขั้นตอนนี้: ได้ที่อยู่เป้าหมายที่ใช้งานได้และสตริงการเชื่อมต่อพร็อกซีที่ถูกต้อง
- กำหนด URL ของเป้าหมายที่จะทดสอบโหลด สมมติว่าเป็นระบบทดสอบของคุณ เช่น ที่อยู่ https://stend.local/api/health
- ตรวจสอบว่าเป้าหมายตอบสนองเร็วและเสถียรเมื่อส่งคำขอเดียวผ่านเบราว์เซอร์ปกติหรือเครื่องมือ curl
- นำข้อมูลพร็อกซี Proxeon จากบัญชีผู้ใช้: โฮสต์ พอร์ต ชื่อผู้ใช้ และรหัสผ่าน
- ประกอบสตริงการเชื่อมต่อในรูปแบบ http://ชื่อผู้ใช้:รหัสผ่าน@โฮสต์:พอร์ต ตัวอย่างเช่น http://user:pass@proxy.proxeon.net:8000
- ตรวจสอบพร็อกซีด้วยคำขอ curl เดี่ยว โดยแทนที่ข้อมูลของคุณในตัวอย่าง
ตัวอย่างคำขอตรวจสอบ:
curl -x http://user:pass@proxy.proxeon.net:8000 -H "Accept: application/json" https://stend.local/api/health⚠️ ข้อควรระวัง: ห้ามเก็บชื่อผู้ใช้และรหัสผ่านพร็อกซีไว้ในโค้ดโดยตรงที่อาจเข้าไปใน repository ให้ใช้ตัวแปรสภาพแวดล้อม (environment variables) เราจะแสดงวิธีในขั้นตอนถัดไป
ผลลัพธ์ที่คาดหวัง: curl ผ่านพร็อกซีส่งคืนคำตอบที่ถูกต้องจากเป้าหมายโดยไม่มีข้อผิดพลาดในการเชื่อมต่อ
ปัญหาที่อาจพบ: หาก curl ค้าง - ตรวจสอบพอร์ตและไฟร์วอลล์ หากมีข้อผิดพลาดการยืนยันตัวตน 407 - ตรวจสอบชื่อผู้ใช้และรหัสผ่านอีกครั้ง
✅ การตรวจสอบ: คุณเห็นเนื้อหาคำตอบจากเป้าหมายโดยได้รับผ่านพร็อกซี แสดงว่าห่วงโซ่ทำงานได้
ขั้นตอนที่ 2: เข้าใจวิธีการทดสอบโหลดที่ถูกต้อง
เป้าหมายของขั้นตอนนี้: เข้าใจว่าทำไมการส่งคำขอพร้อมกันครั้งเดียวจึงไร้ประโยชน์ และวิธีสร้างโปรไฟล์โหลดที่ถูกต้อง
ทำไมการส่งคำขอพร้อมกันครั้งเดียวทำให้เข้าใจผิด
หากคุณส่งคำขอหนึ่งพันคำขอพร้อมกันในคราวเดียว คุณจะได้ตัวเลขที่สวยงาม แต่ไร้ความหมาย การส่งแบบนี้ไม่ได้แสดงพฤติกรรมที่ยั่งยืน ระบบอาจรองรับการพุ่งสูงชั่วคราวได้ด้วยบัฟเฟอร์ แล้วค่อย ๆ เสื่อมลง หรืออาจสำลักตั้งแต่เริ่มเพราะการเชื่อมต่อที่ยังไม่พร้อม
สามช่วงของการทดสอบที่ถูกต้อง
การทดสอบโหลดที่ถูกต้องประกอบด้วยสามช่วง:
- การอุ่นเครื่อง (Warm-up) 30-60 วินาทีแรก ค่อย ๆ เพิ่มโหลด พูลการเชื่อมต่อ แคช DNS และโครงสร้างภายในจะได้อุ่นเครื่อง ข้อมูลช่วงนี้ไม่ควรรวมในสถิติสุดท้าย
- การเพิ่มขึ้นเป็นขั้นบันได (Ramp-up steps) เพิ่มการเชื่อมต่อพร้อมกันเป็นขั้น ๆ เช่น 10, 25, 50, 100, 200 VU โดยหยุดที่แต่ละขั้น 1-2 นาที เพื่อให้เห็นว่าขั้นไหนเริ่มเสื่อมประสิทธิภาพ
- ช่วงคงที่ (Steady state) คงโหลดไว้ที่ระดับต่ำกว่าขีดจำกัดเล็กน้อยเป็นเวลา 5-10 นาที ช่วงนี้แสดงว่าระบบเสถียรภายใต้โหลดต่อเนื่องหรือไม่ มีการรั่วไหลหรือการสะสมของคิวหรือไม่
คำแนะนำ: อย่าสรุปผลจาก 30 วินาทีแรกของการทดสอบ ให้ระบบเข้าสู่สภาวะคงที่ก่อน แล้วค่อยดูตัวเลข
สิ่งที่บันทึกในแต่ละขั้น
- RPS ที่ทำได้
- ความหน่วง p50, p95, p99
- อัตราข้อผิดพลาด
- จำนวน VU หรือเธรดที่ใช้งาน
กำหนดจุดเสื่อมดังนี้: หาขั้นที่หลังจากนั้น RPS หยุดเพิ่มขึ้น แต่ p95 และอัตราข้อผิดพลาดเริ่มเพิ่มขึ้นอย่างรวดเร็ว ขั้นก่อนหน้านั้นคือจุดทำงานที่ปลอดภัยของคุณ
✅ การตรวจสอบ: คุณสามารถอธิบายด้วยคำพูดของคุณเองได้ว่าการอุ่นเครื่องแตกต่างจากช่วงคงที่อย่างไร และทำไมต้องเพิ่มเป็นขั้นบันได
ขั้นตอนที่ 3: k6 - สคริปต์สำเร็จรูปพร้อมพร็อกซีและขั้นโหลด
เป้าหมายของขั้นตอนนี้: สร้างและรันสคริปต์ k6 ที่ใช้งานได้ซึ่งผ่านการอุ่นเครื่อง ขั้นบันได และช่วงคงที่ผ่านพร็อกซี
k6 ทำงานกับพร็อกซีอย่างไร
k6 อ่านที่อยู่พร็อกซีจากตัวแปรสภาพแวดล้อม HTTP_PROXY และ HTTPS_PROXY สะดวกมาก: คุณไม่ต้องใส่ข้อมูลพร็อกซีในสคริปต์ เพียงส่งผ่านตอนรัน
สคริปต์สำเร็จรูป load-test.js
สร้างไฟล์ load-test.js และวางโค้ดต่อไปนี้ลงไป เปลี่ยนที่อยู่เป้าหมายเป็นของคุณ
import http from 'k6/http'; import { check, sleep } from 'k6'; import { Trend, Rate, Counter } from 'k6/metrics'; const latency = new Trend('req_latency', true); const errors = new Rate('req_errors'); const ok = new Counter('req_ok'); export const options = { discardResponseBodies: true, thresholds: { req_errors: ['rate<0.02'], http_req_duration: ['p(95)<1500', 'p(99)<3000'], }, scenarios: { ramp: { executor: 'ramping-vus', startVUs: 0, stages: [ { duration: '1m', target: 10 }, { duration: '2m', target: 25 }, { duration: '2m', target: 50 }, { duration: '2m', target: 100 }, { duration: '2m', target: 200 }, { duration: '5m', target: 200 }, { duration: '1m', target: 0 }, ], gracefulRampDown: '30s', }, }, }; const TARGET = __ENV.TARGET_URL || 'https://stend.local/api/health'; export default function () { const res = http.get(TARGET, { timeout: '10s', tags: { name: 'target' } }); latency.add(res.timings.duration); const good = check(res, { 'status is 200': (r) => r.status === 200 }); errors.add(!good); if (good) ok.add(1); sleep(0.5); }วิธีรันสคริปต์ผ่านพร็อกซี
- เปิดเทอร์มินัลในโฟลเดอร์ที่มีสคริปต์
- ตั้งค่าตัวแปรสภาพแวดล้อมด้วยที่อยู่พร็อกซีและเป้าหมาย บน Linux และ macOS ให้ใช้คำสั่ง export
- รัน k6 ด้วยคำสั่งรันสคริปต์
ตัวอย่างการรันบน Linux และ macOS:
export HTTP_PROXY=http://user:pass@proxy.proxeon.net:8000 export HTTPS_PROXY=http://user:pass@proxy.proxeon.net:8000 export TARGET_URL=https://stend.local/api/health k6 run load-test.jsบน Windows ใน PowerShell ตั้งค่าตัวแปรด้วยไวยากรณ์ $env:
$env:HTTP_PROXY="http://user:pass@proxy.proxeon.net:8000"; $env:HTTPS_PROXY="http://user:pass@proxy.proxeon.net:8000"; $env:TARGET_URL="https://stend.local/api/health"; k6 run load-test.jsคำแนะนำ: พารามิเตอร์ discardResponseBodies ปิดการเก็บเนื้อหาคำตอบไว้ในหน่วยความจำ ซึ่งช่วยลดโหลดบนตัวสร้างโหลดเอง และช่วยไม่ให้สับสนระหว่างการโอเวอร์โหลดของตัวสร้างกับขีดจำกัดของพร็อกซี
การอ่านรายงาน k6
หลังการทดสอบเสร็จสิ้น k6 จะแสดงสรุป ให้สังเกตบรรทัดสำคัญเหล่านี้:
- http_reqs - จำนวนคำขอทั้งหมดและค่า RPS เฉลี่ยในวงเล็บ นี่คือปริมาณงานของคุณ
- http_req_duration - ความหน่วง ซึ่งแสดงค่า avg, min, med, max และเปอร์เซ็นไทล์ p(90), p(95)
- req_errors และ http_req_failed - อัตราข้อผิดพลาด
- vus - จำนวนผู้ใช้เสมือน ณ ขณะนั้น
บรรทัด thresholds จะแสดงว่าเกณฑ์ของคุณผ่านหรือไม่ หากมีเครื่องหมายกากบาทข้างบรรทัด แสดงว่าเกณฑ์ถูกละเมิด หมายความว่าที่การกำหนดค่านี้ถึงหรือเกินขีดจำกัดแล้ว
⚠️ ข้อควรระวัง: ค่า target ใน stages ควรปรับให้เข้ากับระบบของคุณ ค่า 200 VU เป็นเพียงตัวอย่าง หากเป้าหมายหรือขีดจำกัดแพ็กเกจพร็อกซีของคุณน้อยกว่า ให้เริ่มจากขั้นที่เล็กกว่า เช่น สูงสุดที่ 50
ผลลัพธ์ที่คาดหวัง: การทดสอบเสร็จสิ้น และคุณเห็นสรุปที่มี RPS เปอร์เซ็นไทล์ และอัตราข้อผิดพลาด
ปัญหาที่อาจพบ: หากคำขอทั้งหมดล้มเหลว ตรวจสอบตัวแปรพร็อกซี หากตัวสร้างใช้ CPU 100 เปอร์เซ็นต์ - ลดจำนวน VU หรือรันบนเครื่องที่แรงกว่า
✅ การตรวจสอบ: ในสรุป k6 แสดง http_reqs ที่ไม่เป็นศูนย์ และอัตราข้อผิดพลาดต่ำกว่าเกณฑ์ของคุณอย่างน้อยในขั้นแรก ๆ
ขั้นตอนที่ 4: JMeter - สคริปต์เดียวกันพร้อมการตั้งค่าพร็อกซีในแผนการทดสอบ
เป้าหมายของขั้นตอนนี้: สร้างแผนการทดสอบที่เทียบเท่าใน JMeter พร้อมพร็อกซี ขั้นบันได และการเก็บเมตริก
สร้าง Thread Group
- ใน JMeter ที่เปิดอยู่ คลิกขวาที่องค์ประกอบ Test Plan
- เลือก Add - Threads (Users) - Thread Group
- ในช่อง Number of Threads กำหนดจำนวนเธรดสูงสุด เช่น 200
- ในช่อง Ramp-up period กำหนดเวลาในการเพิ่มโหลดเต็มรูปแบบเป็นวินาที เช่น 540 เพื่อจำลองการเพิ่มแบบขั้นบันไดจาก k6
- ในช่อง Loop Count ทำเครื่องหมาย Infinite และกำหนดระยะเวลาด้วย timer และ scheduler
การตั้งค่าพร็อกซีใน HTTP Request Defaults
เพื่อไม่ต้องระบุพร็อกซีในทุกคำขอ เราจะตั้งค่าเพียงครั้งเดียว
- คลิกขวาที่ Thread Group แล้วเลือก Add - Config Element - HTTP Request Defaults
- ในองค์ประกอบที่เปิดขึ้น ให้หาแท็บการตั้งค่าพร็อกซีเซิร์ฟเวอร์
- ในช่อง Server Name or IP (ในบล็อก Proxy) ใส่โฮสต์พร็อกซี เช่น proxy.proxeon.net
- ในช่อง Port Number (Proxy) ใส่พอร์ต เช่น 8000
- ในช่อง Username และ Password (Proxy) ใส่ชื่อผู้ใช้และรหัสผ่านของคุณ
เพิ่ม HTTP Request เอง
- คลิกขวาที่ Thread Group แล้วเลือก Add - Sampler - HTTP Request
- ในช่อง Protocol ใส่ https
- ในช่อง Server Name or IP ใส่โดเมนเป้าหมาย เช่น stend.local
- ในช่อง Path ใส่พาธ เช่น /api/health
- ในช่อง Method ปล่อยเป็น GET
เพิ่มความหน่วงระหว่างคำขอ
- คลิกขวาที่ HTTP Request แล้วเลือก Add - Timer - Constant Timer
- ในช่อง Thread Delay ใส่ 500 มิลลิวินาที เพื่อจำลอง sleep จาก k6
ตั้งค่าการเก็บเมตริก
- คลิกขวาที่ Thread Group แล้วเพิ่ม Add - Listener - Summary Report
- เพิ่ม Add - Listener - Aggregate Report ด้วย - ตัวนี้แสดงเปอร์เซ็นไทล์
- สำหรับการทดสอบระยะยาว อย่าใช้ listener แบบกราฟิก เพราะกินหน่วยความจำ ให้บันทึกผลลัพธ์ลงไฟล์แทน
คำแนะนำ: สำหรับการทดสอบหนัก ให้รัน JMeter ในโหมดไม่แสดงกราฟิกด้วยคำสั่งจากเทอร์มินัล วิธีนี้ตัวสร้างจะใช้ทรัพยากรกับการสร้างโหลด ไม่ใช่การวาดกราฟ
ตัวอย่างการรันในโหมดไม่แสดงกราฟิก:
jmeter -n -t plan.jmx -l results.jtl -e -o reportโดยที่ -n คือรันโดยไม่แสดงกราฟิก -t ระบุไฟล์แผนการทดสอบ -l ระบุไฟล์ผลลัพธ์ดิบ และ -e -o สร้างรายงาน HTML ในโฟลเดอร์ report
การอ่านรายงาน JMeter
เปิด index.html จากโฟลเดอร์ report ตัวชี้วัดสำคัญ:
- Throughput - ปริมาณงานเป็นคำขอต่อวินาที
- Response Times Percentiles - กราฟเปอร์เซ็นไทล์ความหน่วง
- Error percentage - อัตราข้อผิดพลาด
- Active Threads Over Time - การเพิ่มขึ้นของการเชื่อมต่อพร้อมกัน
⚠️ ข้อควรระวัง: ในการยืนยันตัวตนพร็อกซี JMeter อาจต้องตั้งค่า Basic authentication เพิ่มเติม หากเห็นข้อผิดพลาด 407 จำนวนมาก ให้เพิ่มองค์ประกอบ HTTP Authorization Manager พร้อมข้อมูลพร็อกซี
ผลลัพธ์ที่คาดหวัง: รายงาน HTML ของ JMeter เปิดขึ้นและแสดง throughput เปอร์เซ็นไทล์ และอัตราข้อผิดพลาด
✅ การตรวจสอบ: ค่า throughput และเปอร์เซ็นไทล์ใน JMeter ใกล้เคียงกับผลลัพธ์ของ k6 ที่ขั้นเดียวกัน ความคลาดเคลื่อนเล็กน้อยเป็นเรื่องปกติ
ขั้นตอนที่ 5: แยกแยะขีดจำกัดของพร็อกซี ขีดจำกัดของไคลเอนต์ และขีดจำกัดของเซิร์ฟเวอร์ - การตรวจสอบสามอย่าง
เป้าหมายของขั้นตอนนี้: ระบุอย่างแม่นยำว่าโหนดใดในสามโหนดกลายเป็นคอขวด
เมื่อเห็นการเสื่อมประสิทธิภาพ สิ่งสำคัญคือต้องรู้แหล่งที่มา ทำการตรวจสอบสามอย่างต่อไปนี้
การตรวจสอบที่ 1: ไคลเอนต์ของคุณถึงขีดจำกัดหรือไม่
- ระหว่างการทดสอบ เปิด system monitor บนเครื่องที่สร้างโหลด
- สังเกตการใช้งาน CPU และหน่วยความจำของกระบวนการ k6 หรือ JMeter
- ตรวจสอบขีดจำกัด file descriptors บน Linux ด้วยคำสั่ง ulimit -n
หาก CPU ของตัวสร้างใกล้ 100 เปอร์เซ็นต์หรือถึงขีดจำกัด descriptors - ปัญหาอยู่ที่ไคลเอนต์ ไม่ใช่พร็อกซี เพิ่มขีดจำกัด descriptors ลดจำนวน VU หรือใช้เครื่องที่แรงกว่า
คำแนะนำ: สัญญาณของการโอเวอร์โหลดไคลเอนต์คือความหน่วงเพิ่มขึ้นพร้อมกับการใช้งาน CPU ของตัวสร้างที่สูงขึ้นในขณะที่ RPS คงที่ พร็อกซีไม่เกี่ยวข้อง
การตรวจสอบที่ 2: เซิร์ฟเวอร์ปลายทางถึงขีดจำกัดหรือไม่
- รันการทดสอบสั้น ๆ ตรง ๆ โดยไม่ผ่านพร็อกซี โดยลบตัวแปร HTTP_PROXY และ HTTPS_PROXY
- เปรียบเทียบ RPS และเปอร์เซ็นไทล์กับผลลัพธ์ที่ผ่านพร็อกซี
หาก RPS สูงสุดใกล้เคียงกันทั้งแบบตรงและผ่านพร็อกซี - คอขวดอยู่ที่เซิร์ฟเวอร์ปลายทาง พร็อกซีเพิ่มเพียงความหน่วงคงที่เล็กน้อย
⚠️ ข้อควรระวัง: การทดสอบตรง ๆ ให้ทำกับระบบทดสอบของคุณเองเท่านั้น อย่าโหลดทรัพยากรของผู้อื่นโดยไม่ได้รับอนุญาตแม้เพื่อการวินิจฉัย
การตรวจสอบที่ 3: แยกพร็อกซีออกมา
- รัน stub ง่าย ๆ บนระบบทดสอบของคุณที่ตอบ 200 OK ทันทีด้วยเนื้อหาว่าง
- รันการทดสอบผ่านพร็อกซีกับ stub นี้
stub ตอบสนองแทบจะทันที ดังนั้นความหน่วงและขีดจำกัด RPS ตอนนี้จึงถูกกำหนดโดยพร็อกซีและเครือข่ายเป็นหลัก หาก RPS ถึงเพดานที่ stub นี้ - คุณพบขีดจำกัดของพร็อกซีแล้ว
สรุปตรรกะในตารางการตัดสินใจง่าย ๆ:
- CPU ของตัวสร้างสูง RPS ไม่เพิ่ม - ขีดจำกัดของไคลเอนต์
- แบบตรงและผ่านพร็อกซีเหมือนกัน - ขีดจำกัดของเซิร์ฟเวอร์ปลายทาง
- ที่ stub ที่เร็วผ่านพร็อกซี RPS ถึงเพดาน - ขีดจำกัดของพร็อกซี
ผลลัพธ์ที่คาดหวัง: คุณสามารถระบุโหนดเฉพาะที่จำกัดระบบของคุณได้
✅ การตรวจสอบ: คุณทำการตรวจสอบทั้งสามอย่างแล้วและสามารถอธิบายได้ว่าคอขวดอยู่ที่ใด
ขั้นตอนที่ 6: ใช้ผลลัพธ์อย่างไร - เธรด พูล และเวลารันงาน
เป้าหมายของขั้นตอนนี้: แปลงตัวเลขจากการทดสอบเป็นการตั้งค่าที่ใช้งานได้จริงสำหรับงานของคุณ
การเลือกจำนวนเธรดที่ปลอดภัย
ใช้ขั้นก่อนจุดเสื่อม สมมติว่าที่ 100 VU คุณได้ RPS 180 ที่เสถียร p95 ประมาณ 900 มิลลิวินาที และข้อผิดพลาดต่ำกว่า 1 เปอร์เซ็นต์ แต่ที่ 200 VU RPS ไม่เพิ่มขึ้น แต่ p95 พุ่งไปที่ 4 วินาที จุดทำงานที่ปลอดภัยคือประมาณ 100 VU และเพื่อความปลอดภัยให้ใช้ 80-90
การคำนวณขนาดพูลพร็อกซี
หากโหนดพร็อกซีหนึ่งตัวรองรับการเชื่อมต่อพร้อมกัน N รายการอย่างเสถียร และคุณต้องการ M การเชื่อมต่อพร้อมกัน ขนาดพูลขั้นต่ำคือ M หารด้วย N แล้วปัดเศษขึ้นบวกกับเผื่อไว้ เผื่อ 20-30 เปอร์เซ็นต์เพื่อครอบคลุมช่วงที่การเชื่อมต่อบางส่วนถูกครอบครองโดยคำตอบที่ช้า
คำแนะนำ: เผื่อพูลไว้เสมอ คำตอบจริงช้ากว่า stub หมายความว่าการเชื่อมต่อถูกครอบครองนานขึ้น และการเชื่อมต่อพร้อมกันจริงสูงกว่าที่คำนวณได้
การประมาณเวลารันงาน
สูตรง่าย ๆ: เวลาเป็นวินาทีเท่ากับจำนวนคำขอทั้งหมดหารด้วย RPS ที่เสถียร หากคุณต้องเก็บข้อมูล 1,000,000 คำขอที่ RPS 180 ที่เสถียร จะใช้เวลาประมาณ 5556 วินาที หรือประมาณ 1 ชั่วโมง 33 นาที โดยไม่รวมการหยุดและการลองใหม่
- นำ RPS ที่เสถียรจากขั้นทำงาน
- หารปริมาณงานทั้งหมดด้วย RPS นี้
- เพิ่ม 15-20 เปอร์เซ็นต์สำหรับการลองคำขอที่ล้มเหลวและการหยุด
ตัวอย่างการคำนวณใน pseudocode เพื่อความชัดเจน:
total = 1000000; rps = 180; base_sec = total / rps; final_sec = base_sec * 1.2;