คุณได้เขียน HTTP endpoint ขึ้นมา และมันทำงานได้เมื่อคุณเรียกใช้ครั้งเดียวจาก Postman แต่จะเกิดอะไรขึ้นเมื่อมีลูกค้า 200 รายเรียกใช้งานพร้อมกัน? คุณต้องการตัวเลข: จำนวนคำขอต่อวินาที (requests per second), เปอร์เซ็นไทล์ของเวลาแฝง (latency percentiles) และจำนวนการตอบกลับที่มีสถานะไม่ใช่ 2xx autocannon จะให้ตัวเลขเหล่านี้จากเทอร์มินัลของคุณได้ภายในเวลาประมาณสิบวินาที
autocannon เป็นเครื่องมือทดสอบประสิทธิภาพ HTTP/1.1 ที่เขียนด้วย Node.js โดยจะส่งคำขอจำนวนมากอย่างควบคุมไปยัง URL และรายงานปริมาณงาน (throughput) และเวลาแฝง (latency) คู่มือนี้จะแนะนำคุณตั้งแต่การติดตั้ง การรันพื้นฐาน แฟล็กทุกตัวที่คุณจะได้ใช้จริง การอ่านผลลัพธ์ และการใช้งาน autocannon จากสคริปต์ Node นอกจากนี้ยังบอกความแตกต่างอย่างชัดเจนระหว่างสิ่งที่การทดสอบโหลดบอกคุณได้และบอกไม่ได้ เพื่อให้คุณรู้ว่าเมื่อใดควรใช้การทดสอบฟังก์ชันและการทดสอบสัญญาแทน
autocannon คืออะไร
autocannon จะเปิดการเชื่อมต่อพร้อมกันจำนวนหนึ่งไปยัง URL ที่กำหนด และส่งคำขอต่อเนื่องเป็นระยะเวลาที่กำหนด (หรือจำนวนคำขอที่กำหนด) ในขณะที่รันอยู่ จะมีการสุ่มตัวอย่างเวลาแฝงและนับการตอบกลับ เมื่อเสร็จสิ้น จะแสดงตารางเปอร์เซ็นไทล์ของเวลาแฝงและสรุปจำนวนคำขอทั้งหมดและข้อมูลที่อ่านได้

มันวัดเพียงสิ่งเดียว: เซิร์ฟเวอร์ของคุณสามารถรองรับโหลดได้เท่าใด และตอบสนองได้เร็วแค่ไหนภายใต้โหลดนั้น ไม่ได้ตรวจสอบว่าส่วนเนื้อหาการตอบกลับถูกต้องหรือไม่ API ของคุณตรงกับ OpenAPI spec หรือไม่ หรือเวิร์กโฟลว์แบบหลายขั้นตอนส่งคืนข้อมูลที่ถูกต้องในแต่ละขั้นตอนหรือไม่ โปรดจำความแตกต่างนี้ไว้ เพราะมันจะกำหนดว่า autocannon เหมาะสมกับส่วนใดในชุดเครื่องมือการทดสอบของคุณ ซึ่งจะกล่าวถึงในช่วงท้าย
หากคุณเคยใช้ wrk หรือ Apache Bench, autocannon ก็ทำหน้าที่เดียวกัน โดยติดตั้งแบบ Node-native และมี API แบบโปรแกรมที่คุณสามารถเรียกใช้จาก JavaScript ได้
การติดตั้ง
autocannon มาในรูปแบบแพ็กเกจ npm ติดตั้งแบบ global เพื่อให้สามารถใช้คำสั่ง autocannon ได้ทุกที่:
npm i autocannon -g
คุณต้องติดตั้ง Node.js ก่อน หากคุณไม่ต้องการติดตั้งแบบ global สามารถรันได้ตามต้องการด้วย npx:
npx autocannon http://localhost:3000
หรือเพิ่มเป็น dev dependency ให้กับโปรเจกต์ของคุณเมื่อคุณวางแผนที่จะเขียนสคริปต์:
npm i autocannon --save-dev
ยืนยันการติดตั้ง:
autocannon --version
การรันพื้นฐาน
รูปแบบที่ง่ายที่สุดคือคำสั่งพร้อม URL ซึ่งจะรันการทดสอบประสิทธิภาพเริ่มต้น: การเชื่อมต่อ 10 ครั้ง เป็นเวลา 10 วินาที
autocannon http://localhost:3000
ปรับแต่งด้วยสามแฟล็กที่คุณจะใช้บ่อย -c กำหนดจำนวนการเชื่อมต่อพร้อมกัน -d กำหนดระยะเวลาเป็นวินาที และ -p กำหนด pipelining (จำนวนคำขอที่แต่ละการเชื่อมต่อส่งไปก่อนรอการตอบกลับ)
autocannon -c 100 -d 30 -p 10 http://localhost:3000
คำสั่งนั้นจะเปิดการเชื่อมต่อ 100 ครั้ง รันเป็นเวลา 30 วินาที และส่งคำขอแบบ pipelining 10 คำขอต่อการเชื่อมต่อ การเพิ่มจำนวนการเชื่อมต่อและ pipelining จะสร้างโหลดที่มากขึ้น ซึ่งเป็นวิธีที่คุณจะพบจุดที่เวลาแฝงเริ่มสูงขึ้น
หากต้องการส่งคำขอจำนวนที่แน่นอนแทนการรันตามระยะเวลา ให้ใช้ -a (จำนวน):
autocannon -c 10 -a 10000 http://localhost:3000
คำสั่งนี้จะหยุดหลังจากส่งคำขอ 10,000 ครั้ง โดยไม่ขึ้นกับเวลา
คำขอ POST, เฮดเดอร์ และเนื้อหา (Body)
เปลี่ยนเมธอดด้วย -m, เพิ่มเฮดเดอร์ด้วย -H, และส่งเนื้อหาคำขอด้วย -b นี่คือตัวอย่างคำขอ POST ไปยัง JSON endpoint:
autocannon -c 50 -d 20 \
-m POST \
-H 'Content-Type=application/json' \
-H 'Authorization=Bearer YOUR_TOKEN' \
-b '{"name":"load-test","active":true}' \
http://localhost:3000/api/users
โปรดสังเกตรูปแบบเฮดเดอร์: -H 'Key=Value' และคุณต้องทำซ้ำ -H สำหรับแต่ละเฮดเดอร์ หากเนื้อหาของคุณมีขนาดใหญ่หรืออยู่ในไฟล์ ให้ใช้ -i เพื่ออ่านจากดิสก์แทนการใส่เป็นข้อความในบรรทัดเดียว:
autocannon -m POST -H 'Content-Type=application/json' -i payload.json http://localhost:3000/api/users
การจำกัดอัตราการทดสอบ (Rate Limiting)
โดยค่าเริ่มต้น autocannon จะส่งคำขอให้เร็วที่สุดเท่าที่จะทำได้ บางครั้งคุณอาจต้องการอัตราที่คงที่และสมจริง แทนที่จะเป็นการส่งคำขออย่างรุนแรงสูงสุด -R จะจำกัดจำนวนคำขอทั้งหมดต่อวินาทีในการเชื่อมต่อทั้งหมด:
autocannon -c 50 -R 500 -d 60 http://localhost:3000
คำสั่งนี้จะรันการทดสอบที่ 500 คำขอต่อวินาที เป็นเวลา 60 วินาที ซึ่งมีประโยชน์เมื่อคุณต้องการวัดเวลาแฝงภายใต้โหลดการใช้งานจริงที่คาดการณ์ไว้ แทนที่จะวัด ณ จุดที่ระบบพัง
การวอร์มอัพ (Warmup) และเธรดการทำงาน (Worker Threads)
อีกสองแฟล็กมีประโยชน์สำหรับการรันที่หนักขึ้น -W (warmup) จะส่งทราฟฟิกในช่วงสั้นๆ ก่อนที่ autocannon จะเริ่มเก็บตัวอย่าง เพื่อไม่ให้ตัวเลขเริ่มต้นของคุณผิดเพี้ยนจากการแคชที่ยังไม่พร้อมใช้งานหรือ JIT ที่ยังไม่ได้วอร์มอัพ -w (workers) จะกระจายโหลดไปทั่วเธรดการทำงานของ Node หลายเธรด ซึ่งสำคัญเมื่อเธรดเดียวไม่สามารถสร้างคำขอได้เพียงพอที่จะทำให้เซิร์ฟเวอร์ที่เร็วทำงานเต็มประสิทธิภาพ:
autocannon -c 200 -d 30 -w 4 http://localhost:3000
ควรใช้ -w เมื่อคุณแน่ใจแล้วว่าตัวสร้างโหลดเองเป็นคอขวด หากเวลาแฝงดูราบเรียบผิดปกติเมื่อคุณเพิ่ม -c ตัวสร้างโหลดของคุณอาจถึงขีดจำกัดแล้ว การเพิ่ม workers จะช่วยให้คุณเห็นขีดจำกัดสูงสุดของเซิร์ฟเวอร์ได้ชัดเจนขึ้น
การอ่านผลลัพธ์
เมื่อการรันเสร็จสิ้น autocannon จะแสดงตารางเวลาแฝงและบรรทัดสรุป นี่คือตัวอย่างย่อ:
Running 10s test @ http://localhost:3000
10 connections
┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬──────────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼──────────┤
│ Latency │ 0 ms │ 1 ms │ 4 ms │ 6 ms │ 1.2 ms │ 0.9 ms │ 24.1 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴──────────┘
251k requests in 10.05s, 27.9 MB read
วิธีการอ่านมีดังนี้:
- คอลัมน์เปอร์เซ็นไทล์ (2.5%, 50%, 97.5%, 99%) มีความสำคัญมากกว่าค่าเฉลี่ย คอลัมน์ 50% คือค่ามัธยฐาน คอลัมน์ 99% จะบอกเวลาแฝงที่ 1 เปอร์เซ็นต์ของผู้ใช้ที่ช้าที่สุดของคุณได้รับ Tail latency คือจุดที่ปัญหาจริงซ่อนอยู่ ดังนั้นควรให้ความสนใจกับตัวเลข 97.5% และ 99%
- Avg (ค่าเฉลี่ย) และ Stdev (ส่วนเบี่ยงเบนมาตรฐาน) จะบอกค่าเฉลี่ยและช่วงการกระจายของเวลาแฝง ค่าส่วนเบี่ยงเบนมาตรฐานที่สูงหมายถึงเวลาตอบสนองที่ไม่สอดคล้องกัน
- บรรทัดสรุป (“251k requests in 10.05s”) คือปริมาณงาน (throughput) ของคุณ หารจำนวนคำขอด้วยจำนวนวินาทีเพื่อหาจำนวนคำขอต่อวินาที
แฟล็กสองตัวนี้ทำให้ผลลัพธ์มีประโยชน์มากขึ้น เพิ่ม -l เพื่อพิมพ์ชุดเปอร์เซ็นไทล์ของเวลาแฝงทั้งหมด (รวมถึง p99.9 และสูงกว่า) และเพิ่ม --renderStatusCodes เพื่อดูรายละเอียดแยกตามรหัสสถานะ เพื่อให้คุณสามารถตรวจจับสถานะ 500s จำนวนมากที่ซ่อนอยู่เบื้องหลังตัวเลข throughput ที่ดูดีได้:
autocannon -c 100 -d 20 -l --renderStatusCodes http://localhost:3000
ให้สังเกตข้อผิดพลาด, การหมดเวลา (timeouts) และจำนวนสถานะที่ไม่ใช่ 2xx เซิร์ฟเวอร์อาจแสดงอัตราคำขอสูงในขณะที่ยังคงส่งคืนข้อผิดพลาดโดยไม่เปิดเผย หากสถานะที่ไม่ใช่ 2xx ไม่เป็นศูนย์ ตัวเลขปริมาณงานของคุณกำลังวัดความล้มเหลว ไม่ใช่ความสำเร็จ
การใช้งานแบบโปรแกรมในสคริปต์
autocannon มี API ของ Node.js ให้คุณสามารถรันการทดสอบประสิทธิภาพจากสคริปต์และดำเนินการตามผลลัพธ์ได้ นี่คือจุดที่มันมีคุณค่าในระบบอัตโนมัติ: รันการทดสอบ อ่านตัวเลข และทำให้บิลด์ล้มเหลวหากเวลาแฝงเกินเกณฑ์ที่กำหนด
การเรียกใช้งานหลักจะรับออบเจกต์ตัวเลือกและส่งคืน Promise:
const autocannon = require('autocannon')
async function run() {
const result = await autocannon({
url: 'http://localhost:3000',
connections: 100,
duration: 20,
pipelining: 1
})
console.log(`Avg latency: ${result.latency.average} ms`)
console.log(`Req/sec: ${result.requests.average}`)
console.log(`Non-2xx: ${result.non2xx}`)
}
run()
ออบเจกต์ result จะมีฮิสโทแกรมสำหรับ latency (เวลาแฝง), requests (คำขอ) และ throughput (ปริมาณงาน) โดยแต่ละอันจะมีฟิลด์ average (เฉลี่ย), min (ต่ำสุด), max (สูงสุด) และฟิลด์เปอร์เซ็นไทล์ เช่น p99 นอกจากนี้ยังมี errors (ข้อผิดพลาด), timeouts (การหมดเวลา) และ non2xx (จำนวนสถานะที่ไม่ใช่ 2xx) อีกด้วย
ในการเปลี่ยนเป็นเกณฑ์ (gate) ให้เพิ่มการตรวจสอบที่ทำให้โปรแกรมหยุดทำงานโดยส่งคืนค่าที่ไม่ใช่ศูนย์เมื่อเกินงบประมาณที่กำหนด:
const autocannon = require('autocannon')
const P99_BUDGET_MS = 250
async function run() {
const result = await autocannon({
url: 'http://localhost:3000/api/health',
connections: 100,
duration: 30
})
const p99 = result.latency.p99
console.log(`p99 latency: ${p99} ms (budget ${P99_BUDGET_MS} ms)`)
if (p99 > P99_BUDGET_MS || result.non2xx > 0) {
console.error('Performance budget exceeded')
process.exit(1)
}
}
run()
หากคุณต้องการแถบความคืบหน้าแบบสดและตารางผลลัพธ์ที่ CLI แสดง ให้ส่ง instance ไปยัง autocannon.track:
const autocannon = require('autocannon')
const instance = autocannon({
url: 'http://localhost:3000',
connections: 10,
duration: 10
}, console.log)
autocannon.track(instance, { renderProgressBar: true })
process.once('SIGINT', () => instance.stop())
สำหรับสถานการณ์ที่มีคำขอหลายรายการ ให้ส่งอาร์เรย์ requests เพื่อให้แต่ละการเชื่อมต่อวนเวียนผ่านการเรียกใช้หลายครั้ง:
autocannon({
url: 'http://localhost:3000',
connections: 20,
duration: 15,
requests: [
{ method: 'GET', path: '/api/users' },
{ method: 'POST', path: '/api/data', body: '{"x":1}',
headers: { 'Content-Type': 'application/json' } }
]
}, console.log)
autocannon เทียบกับ wrk และ ab
ทั้งสามเครื่องมือตอบคำถามเดียวกัน (เร็วแค่ไหน, ภายใต้โหลดเท่าใด) และการเลือกใช้เครื่องมือที่เหมาะสมขึ้นอยู่กับสแต็กเทคโนโลยีของคุณ
- Apache Bench (ab) เป็นเครื่องมือแบบไบนารีเดี่ยวแบบคลาสสิก มีอยู่ทุกที่และใช้งานง่าย แต่เป็นแบบเธรดเดียวและค่อนข้างเก่า
- wrk นั้นเร็วและสามารถสร้างโหลดที่หนักได้ด้วย Lua scripting สำหรับคำขอที่กำหนดเอง เป็นเครื่องมือที่คอมไพล์จากภาษา C ดังนั้นคุณต้องติดตั้งภายนอก npm
- autocannon มีประสิทธิภาพด้าน throughput เทียบเท่า wrk สำหรับเวิร์กโหลดส่วนใหญ่ และเหนือกว่าในด้านความสะดวกในการใช้งานหากคุณใช้ Node อยู่แล้ว: ใช้
npm iในการติดตั้ง, มี JavaScript API สำหรับเขียนสคริปต์ และรองรับ pipelining, ไฟล์ HAR และสถานการณ์แบบ per-request ได้ทันที
หาก Node เป็นรันไทม์ของคุณ autocannon เป็นตัวเลือกที่ใช้งานง่าย หากคุณชอบเครื่องมือ Python? ดู วิธีทดสอบโหลดโดยไม่ต้องใช้ Python หากต้องการตัวเลือกที่เขียนสคริปต์ได้พร้อมคุณสมบัติมากมาย? เปรียบเทียบ k6 load testing
การทดสอบฟังก์ชัน (Functional Testing) และ Apidog มีบทบาทอย่างไร
autocannon บอกคุณว่า endpoint ของคุณรองรับคำขอได้ 12,000 คำขอต่อวินาที โดยมี p99 อยู่ที่ 40 ms แต่ไม่ได้บอกคุณว่า endpoint นั้นส่งคืนข้อมูลที่ถูกต้องหรือไม่ การทดสอบโหลดอาจผ่านฉลุยในขณะที่ API ส่งคืน JSON ที่ผิดพลาด, ละเว้น auth header หรือเบี่ยงเบนจาก OpenAPI contract ปริมาณงาน (Throughput) ไม่ใช่ความถูกต้อง (Correctness)
นั่นคือช่องว่างที่การทดสอบฟังก์ชันและสัญญาเข้ามาเติมเต็ม และเป็นจุดที่ Apidog เข้ามาเสริมเครื่องมือโหลด แทนที่จะเข้ามาแทนที่ Apidog ไม่ใช่ตัวสร้างโหลด แต่จะรันสถานการณ์ทดสอบที่บันทึกไว้ ซึ่งยืนยันรหัสสถานะ, สกีมาการตอบกลับ และค่าต่างๆ ในเวิร์กโฟลว์แบบหลายขั้นตอน เพื่อให้คุณสามารถจับข้อผิดพลาดที่การทดสอบประสิทธิภาพมองไม่เห็น
คุณสามารถรันทั้งสองอย่างใน CI และทั้งสองจะตอบคำถามที่ต่างกัน ใช้ autocannon (หรือ wrk) เพื่อตอบคำถามว่า "มันเร็วพอภายใต้โหลดหรือไม่?" ใช้ Apidog CLI เพื่อตอบคำถามว่า "มันถูกต้องหรือไม่?" Apidog CLI เป็นแบบ headless และรันสถานการณ์ทดสอบหรือชุดทดสอบที่บันทึกไว้จากขั้นตอน CI ใดๆ ที่มี Node:
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
แฟล็ก -t กำหนดเป้าหมายไปยังสถานการณ์, โฟลเดอร์ หรือชุดทดสอบที่บันทึกไว้ด้วย ID, -e เลือกสภาพแวดล้อม และ -r เลือกหนึ่งหรือหลายตัวสร้างรายงาน (cli, html, json, junit) เพื่อให้การรันสร้างอาร์ติแฟกต์ที่ pipeline ของคุณสามารถเก็บถาวรได้ สำหรับคำแนะนำฉบับเต็ม โปรดดู วิธีรันการทดสอบ API จาก Apidog CLI, pipeline CI/CD แบบคัดลอก-วาง และ GitHub Actions workflow
pipeline ที่ดีจะรันการตรวจสอบฟังก์ชันและสัญญาในทุกการ push (มันทำงานได้หรือไม่?) จากนั้นรันการทดสอบโหลดก่อนการเผยแพร่ (มันรองรับได้หรือไม่?) autocannon ตอบคำถามที่สอง ส่วน Apidog ตอบคำถามแรก
คำถามที่พบบ่อย (FAQ)
autocannon มีความแม่นยำสำหรับการทดสอบโหลดใน Production หรือไม่?
autocannon สร้างตัวเลข throughput และ latency ที่เชื่อถือได้สำหรับ HTTP/1.1 endpoints และเมื่อคุณกำหนดอัตราเป้าหมายด้วย -R มันจะแก้ไขปัญหา coordinated omission ซึ่งเป็นขั้นตอนที่เครื่องมือที่เรียบง่ายหลายตัวข้ามไป เพื่อให้ได้ผลลัพธ์ที่แม่นยำ ควรรันจากเครื่องที่อยู่ใกล้กับเซิร์ฟเวอร์ของคุณ (มิฉะนั้นเวลาแฝงของเครือข่ายจะส่งผลกระทบอย่างมาก) และใช้การเชื่อมต่อให้เพียงพอที่จะทำให้ endpoint ทำงานเต็มประสิทธิภาพ รันกับการทดสอบบนสภาพแวดล้อม staging ที่จำลองสภาพแวดล้อม production ไม่ใช่รันกับ dev server บนแล็ปท็อปของคุณ
autocannon รองรับ HTTP/2 หรือ WebSockets หรือไม่?
ไม่ autocannon ทดสอบประสิทธิภาพ HTTP/1.1 สำหรับการทดสอบโหลด HTTP/2 หรือ WebSocket คุณต้องใช้เครื่องมืออื่น นี่คือข้อจำกัดหลักที่คุณควรตรวจสอบก่อนเลือกใช้
ฉันควรใช้การเชื่อมต่อกี่ครั้ง?
เริ่มต้นที่ค่าเริ่มต้นคือ 10 จากนั้นเพิ่ม -c จนกว่าจำนวนคำขอต่อวินาทีจะหยุดเพิ่มขึ้นและเวลาแฝงเริ่มสูงขึ้น จุดเปลี่ยนนั้นคือความจุของเซิร์ฟเวอร์ของคุณ การเพิ่มเกินจุดนั้นมากเกินไปจะเป็นการวัดขีดจำกัดของตัวสร้างโหลดของคุณมากกว่าของเซิร์ฟเวอร์ของคุณ
ฉันสามารถรัน autocannon ใน CI ได้หรือไม่?
ได้ API แบบโปรแกรมถูกสร้างมาเพื่อสิ่งนี้: รันการทดสอบประสิทธิภาพ, อ่าน result.latency.p99 และ result.non2xx และเรียก process.exit(1) เมื่อเกินงบประมาณที่กำหนด นั่นจะเปลี่ยนการทดสอบประสิทธิภาพให้เป็นเกณฑ์ผ่าน/ไม่ผ่านที่คุณสามารถเชื่อมโยงกับขั้นตอน CI ใดๆ ที่รองรับ Node ได้
ความแตกต่างระหว่าง -a และ -d คืออะไร?
-d จะรันเป็นระยะเวลาจำนวนวินาที -a จะรันจนกว่าจำนวนคำขอจะเสร็จสมบูรณ์แล้วจึงหยุด ใช้ -d สำหรับการทดสอบโหลดแบบ steady-state และ -a เมื่อคุณต้องการส่งจำนวนคำขอที่แน่นอน
