การทดสอบแรงกดดัน

ปัจจัยที่มีผลต่อผลการทดสอบแรงกดดัน

  • ความหน่วงของเครือข่ายระหว่างเครื่องทดสอบกับเซิร์ฟเวอร์ (แนะนำให้ทดสอบภายในเครือข่ายภายในหรือเครื่องของตัวเอง)
  • แบนด์วิธระหว่างเครื่องทดสอบกับเซิร์ฟเวอร์ (แนะนำให้ทดสอบภายในเครือข่ายภายในหรือเครื่องของตัวเอง)
  • การเปิดใช้งาน HTTP keep-alive หรือไม่ (แนะนำให้เปิด)
  • จำนวนการเชื่อมต่อพร้อมกันเพียงพอหรือไม่ (ควรเปิดเชื่อมต่อพร้อมกันสูงขึ้นเมื่อต้องทำการทดสอบจากเครือข่ายภายนอก)
  • จำนวนกระบวนการของเซิร์ฟเวอร์มีความเหมาะสมหรือไม่ (จำนวนกระบวนการสำหรับธุรกิจ helloworld แนะนำให้เท่ากับจำนวน CPU, และจำนวนกระบวนการสำหรับฐานข้อมูลแนะนำให้เป็นสี่เท่าของ CPU หรือมากกว่า)
  • ประสิทธิภาพของธุรกิจอย่างแท้จริง (เช่น การใช้ฐานข้อมูลจากเครือข่ายภายนอกหรือไม่)

HTTP keep-alive คืออะไร?

กลไก HTTP Keep-Alive เป็นเทคนิคที่ใช้สำหรับการส่ง HTTP requests และ responses หลายๆ รายการผ่านการเชื่อมต่อ TCP เดียว ซึ่งมีผลกระทบต่อผลการทดสอบประสิทธิภาพเป็นอย่างมาก โดยปิดการใช้งาน keep-alive อาจทำให้ QPS ลดลงอย่างมาก
ปัจจุบันเบราว์เซอร์ส่วนใหญ่มีการเปิดใช้งาน keep-alive โดยค่าเริ่มต้น ซึ่งหมายความว่าเมื่อเบราว์เซอร์เข้าถึง URL HTTP หนึ่งจะเก็บการเชื่อมต่อไว้ชั่วคราวและไม่ปิด โดยเมื่อมีการร้องขอครั้งถัดไปจะใช้การเชื่อมต่อนี้ซ้ำ เพื่อเพิ่มประสิทธิภาพ
แนะนำให้เปิดใช้งาน keep-alive เมื่อทำการทดสอบแรงกดดัน
นอกจากนี้ ถ้าไม่ได้เปิดใช้งาน keep-alive การทดสอบแรงกดดันจะทำให้พอร์ตท้องถิ่นของไคลเอนต์หมดไปใกล้เคียงกับสถานะ timewait ส่งผลให้จำนวนคำขอทั้งหมดเกินกว่าจำนวนที่กำหนด (โดยปกติประมาณ 28,000) จะมีการร้องขอล้มเหลว

จะเปิดใช้งาน HTTP keep-alive ในระหว่างการทดสอบแรงกดดันได้อย่างไร?

หากใช้โปรแกรม ab สำหรับการทดสอบจำเป็นต้องเพิ่มตัวเลือก -k,例如 ab -n100000 -c200 -k http://127.0.0.1:8787/
apipost ต้องให้หัวกลับคืนมาพร้อม gzip header เพื่อนำไปเปิดใช้งาน keep-alive (ข้อบกพร่องของ apipost ให้ดูที่ด้านล่าง)
โปรแกรมทดสอบแรงกดดันอื่นๆ มักจะเปิดใช้งานโดยค่าเริ่มต้น

ทำไม QPS ถึงต่ำเมื่อทดสอบจากเครือข่ายภายนอก?

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

ทำไมประสิทธิภาพลดลงเมื่อผ่าน nginx proxy?

การทำงานของ nginx จะใช้ทรัพยากรของระบบ นอกจากนี้ การสื่อสารระหว่าง nginx และ webman ก็ต้องใช้ทรัพยากรด้วย
อย่างไรก็ตาม ทรัพยากรของระบบมีอยู่อย่างจำกัด webman ไม่สามารถเข้าถึงทรัพยากรทั้งหมดของระบบ จึงเป็นที่ปกติที่ประสิทธิภาพของระบบโดยรวมอาจลดลง
เพื่อพยายามลดผลกระทบต่อประสิทธิภาพที่เกิดจาก nginx proxy ให้พิจารณาปิดบันทึก nginx (access_log off;),
เปิดใช้งาน keep-alive ระหว่าง nginx ถึง webman โดยอ้างอิงจากnginx proxy

นอกจากนี้ HTTPS จะใช้ทรัพยากรมากกว่าการใช้งาน HTTP เนื่องจาก HTTPS ต้องมีการจัดการ SSL/TLS handshake, การเข้ารหัสและถอดรหัสข้อมูล, ขนาดของแพ็คเกจที่ใหญ่ขึ้นใช้แบนด์วิธมากขึ้นสิ่งเหล่านี้ทำให้ประสิทธิภาพลดลง
หากการทดสอบใช้การเชื่อมต่อแบบสั้น (ไม่มีการเปิด HTTP keep-alive) การร้องขอแต่ละครั้งจะต้องทำการเป็นส่วนหนึ่งของการสื่อสาร SSL/TLS handshake เพิ่มเติม ซึ่งจะส่งผลให้ประสิทธิภาพลดลงอย่างมาก แนะนำให้การทดสอบ HTTPS เปิดใช้งาน HTTP keep-alive

จะรู้ได้อย่างไรว่าเมื่อไหร่ระบบได้ถึงขีดจำกัดด้านประสิทธิภาพแล้ว?

โดยทั่วไป เมื่อ CPU ถึง 100% จะถือว่าประสิทธิภาพของระบบได้ถึงขีดจำกัดแล้ว หาก CPU ยังมีพื้นที่ว่างอยู่แสดงว่ายังไม่ได้ถึงขีดจำกัด ในขณะนั้นสามารถเพิ่มจำนวนการเชื่อมต่อพร้อมกันเพื่อเพิ่ม QPS
หากการเพิ่มจำนวนการเชื่อมต่อพร้อมกันไม่สามารถเพิ่ม QPS ได้ อาจเป็นเพราะจำนวนกระบวนการของ webman ไม่เพียงพอ กรุณาเพิ่มจำนวนกระบวนการของ webman หากยังไม่สามารถเพิ่มได้ให้พิจารณาแบนด์วิธเพียงพอหรือไม่

ทำไมผลการทดสอบของฉันแสดงให้เห็นว่า ประสิทธิภาพของ webman ต่ำกว่าเฟรมเวิร์ก gin ของ go?

การทดสอบจากtechempower แสดงให้เห็นว่าไม่ว่าในกรณีใดเว็บแมนจะมีค่าตัวชี้วัดสูงกว่า gin ประมาณหนึ่งเท่าตัว
หากผลของคุณไม่เช่นนั้นอาจเป็นเพราะคุณใช้ ORM ใน webman ซึ่งอาจส่งผลกระทบต่อประสิทธิภาพ พยายามเปรียบเทียบ webman+PDO ดั้งเดิม กับ gin+SQL ดั้งเดิม

การใช้ ORM ใน webman จะลดประสิทธิภาพไปเท่าไหร่?

ด้านล่างนี้เป็นชุดข้อมูลการทดสอบ

สภาพแวดล้อม
เซิร์ฟเวอร์ Aliyun 4 คอร์ 4G ฐานข้อมูล MySQL ภายในเครื่อง ทำการสุ่มค้นหาข้อมูลหนึ่งรายการจาก 100,000 รายการ แล้วส่งกลับในรูปแบบ json โดยกำลังทดสอบในเครื่อง

หากใช้ PDO ดั้งเดิม
webman QPS คือ 17,800

หากใช้ laravel ของ Db::table()
webman QPS ลดลงเหลือ 9,400 QPS

หากใช้ laravel ของ Model
webman QPS ลดลงเหลือ 7,200 QPS

ผลลัพธ์จาก thinkORM จะคล้ายกันไม่แตกต่างมาก

คำเตือน
แม้ว่าการใช้ ORM จะทำให้ประสิทธิภาพลดลง แต่สำหรับธุรกิจ 99% แล้วประสิทธิภาพยังถือว่ามีการขยายเกินไป หากคุณคือ 1% นั้นก็สามารถเพียงแค่เพิ่ม CPU หรือเซิร์ฟเวอร์ก็สามารถแก้ปัญหาได้อย่างง่ายดาย
เราควรหาจุดสมดุลในหลากหลายตัวชี้วัดเช่น ประสิทธิภาพในการพัฒนา, ความสามารถในการบำรุงรักษา, และประสิทธิภาพ แทนที่จะมุ่งเน้นไปที่ประสิทธิภาพเพียงอย่างเดียว

ทำไมใช้ apipost ทดสอบ QPS ถึงต่ำ?

โมดูลทดสอบแรงกดดันของ apipost มีข้อบกพร่อง หากเซิร์ฟเวอร์ไม่ส่งกลับ gzip header จะไม่สามารถรักษาการเชื่อมต่อ keep-alive ไว้ได้ ทำให้ประสิทธิภาพลดลงมาก
วิธีแก้ปัญหาคือส่งกลับข้อมูลที่ถูกบีบอัดในขณะที่เพิ่ม gzip header เช่น

<?php
namespace app\controller;
class IndexController
{
    public function index()
    {
        return response(gzencode('hello webman'))->withHeader('Content-Encoding', 'gzip');
    }
}

นอกจากนี้ apipost บางครั้งไม่สามารถให้แรงกดดันที่พอใจได้ซึ่งสะท้อนให้เห็นว่าจำนวนการเชื่อมต่อเดียวกันการใช้ apipost จะต่ำกว่า ab ประมาณ 50%
แนะนำให้ใช้ ab, wrk หรือซอฟต์แวร์ทดสอบแรงกดดันอื่น ๆ แทนที่จะใช้ apipost

ตั้งค่าจำนวนกระบวนการให้เหมาะสม

webman เปิดใช้งานจำนวนกระบวนการ cpu*4 โดยค่าเริ่มต้น ในความเป็นจริงการทดสอบแรงกดดันของธุรกิจ helloworld ที่ไม่มี IO ในเครือข่าย ควรตั้งจำนวนกระบวนการให้ตรงกับจำนวนคอร์ CPU เพื่อให้ประสิทธิภาพดีที่สุด เพราะจะช่วยลดต้นทุนการสลับกระบวนการ
หากเป็นธุรกิจที่มีฐานข้อมูล, Redis เป็นต้นที่เป็นการรองรับ I/O ที่เป็นบล็อก ควรตั้งค่าจำนวนกระบวนการเป็น 3-8 เท่าของ CPU เพราะในช่วงเวลานั้นต้องการจำนวนกระบวนการมากขึ้นเพื่อเพิ่มการเชื่อมต่อพร้อมกัน แต่ต้นทุนการสลับกระบวนการจะน้อยมากเมื่อเทียบกับ I/O ที่เป็นบล็อก

ขอบเขตอ้างอิงสำหรับการทดสอบแรงกดดัน

เซิร์ฟเวอร์คลาวด์ 4 คอร์ 4G 16 กระบวนการ ทดสอบในเครื่อง/เครือข่ายภายใน

- เปิดใช้งาน keep-alive ไม่เปิดใช้งาน keep-alive
hello world 80,000-160,000 QPS 10,000-30,000 QPS
การค้นหารายการเดี่ยวในฐานข้อมูล 10,000-20,000 QPS 10,000 QPS

ข้อมูลการทดสอบจากบุคคลที่สาม techempower

ตัวอย่างคำสั่งทดสอบแรงกดดัน

ab

# 100000 คำขอ 200 การเชื่อมต่อพร้อมกัน เปิดใช้งาน keep-alive
ab -n100000 -c200 -k http://127.0.0.1:8787/

# 100000 คำขอ 200 การเชื่อมต่อพร้อมกัน ไม่เปิดใช้งาน keep-alive
ab -n100000 -c200 http://127.0.0.1:8787/

wrk

# 200 การเชื่อมต่อพร้อมกัน ทดสอบเป็นเวลา 10 วินาที เปิดใช้งาน keep-alive (ตามค่าเริ่มต้น)
wrk -c 200 -d 10s http://example.com