wrk: วิธีทดสอบโหลด API จาก Command Line

เรียนรู้วิธีทดสอบโหลด API ด้วย wrk จากบรรทัดคำสั่ง: การติดตั้ง, แฟล็กสำหรับเธรดและการเชื่อมต่อ, การอ่านผลลัพธ์ของค่าความหน่วง, และการร้องขอแบบ POST ผ่าน Lua

Ashley Innocent

Ashley Innocent

6 July 2026

wrk: วิธีทดสอบโหลด API จาก Command Line

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

คุณได้นำ Endpoint ไปใช้งานแล้ว และมันทำงานได้ดีในเบราว์เซอร์ของคุณ แต่คุณไม่มีทางรู้เลยว่าจะเกิดอะไรขึ้นเมื่อมีคน 400 คนเข้าใช้งานพร้อมกัน ค่า Latency จะคงที่ หรือว่าค่าเปอร์เซ็นไทล์ที่ 99 จะพุ่งสูงขึ้นจนควบคุมไม่ได้? เซิร์ฟเวอร์จะรองรับได้ 1,000 requests ต่อวินาที หรือจะล่มที่ 300 requests?

wrk คือคำตอบสำหรับคำถามเหล่านี้ มันเป็นเครื่องมือ command-line ขนาดเล็กที่ส่งทราฟฟิก HTTP จำนวนมากไปยัง URL และรายงานว่าเซิร์ฟเวอร์ตอบสนองได้เร็วแค่ไหนภายใต้โหลดนั้น

button

wrk คืออะไร และควรใช้เมื่อใด

wrk เป็นเครื่องมือสำหรับทดสอบประสิทธิภาพ HTTP ที่ทันสมัย มันสร้างโหลดจากเครื่อง Multi-core เพียงเครื่องเดียว และวัดค่า Latency และอัตรา Request ที่เซิร์ฟเวอร์ตอบกลับมา มันใช้ Multithreading พร้อมกับ Scalable Event Loop (epoll บน Linux, kqueue บน macOS) ดังนั้น Instance เดียวจึงสามารถสร้างทราฟฟิกจำนวนมากได้โดยไม่จำเป็นต้องใช้ Load Box หลายเครื่อง

เลือกใช้ wrk เมื่อคุณต้องการตัวเลขประสิทธิภาพดิบๆ:

wrk เป็นเครื่องมือสำหรับการทดสอบประสิทธิภาพ (benchmarking tool) ไม่ใช่ชุดทดสอบ (test suite) มันวัดความเร็ว ไม่ได้ตรวจสอบว่า Body ของ JSON ถูกต้องหรือไม่, Status Code เป็น 200 หรือไม่ หรือ API ทำงานตามสัญญาหรือไม่ โปรดจำความแตกต่างนี้ไว้ เราจะกลับมาพูดถึงเรื่องนี้อีกครั้งในช่วงท้าย เพราะมันจะเปลี่ยนวิธีการนำ wrk ไปใช้ใน Workflow การทดสอบจริง หากคุณต้องการภาพรวมก่อน คู่มือการทดสอบโหลด API นี้จะครอบคลุมแนวคิดที่ wrk นำมาใช้งานจริง

การติดตั้ง wrk

macOS

Homebrew มีไบนารีที่สร้างไว้ล่วงหน้า ซึ่งเป็นวิธีที่ง่ายที่สุด:

brew install wrk

บน Apple Silicon นี่เป็นสิ่งสำคัญ การสร้างจาก Source Code อาจพบปัญหา LuaJIT ARM64 ได้ ดังนั้นการใช้ไบนารีของ Homebrew จะช่วยลดความยุ่งยากไปได้Linux (สร้างจาก Source Code)

ไม่มีแพ็คเกจ apt อย่างเป็นทางการ คุณจึงต้องสร้างเอง ติดตั้ง Toolchain และ OpenSSL Headers ก่อน:

sudo apt-get install build-essential libssl-dev git -y

จากนั้นโคลนและคอมไพล์:

git clone https://github.com/wg/wrk.git
cd wrk
make

สิ่งนี้จะสร้างไบนารี wrk ในไดเรกทอรีปัจจุบัน ย้ายไปที่ PATH ของคุณเพื่อให้สามารถเรียกใช้ได้จากทุกที่:sudo cp wrk /usr/local/bin

ยืนยันว่าทำงานได้:

wrk --version

คำสั่งพื้นฐาน

นี่คือรูปแบบการรัน wrk ทุกครั้ง:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

มีสี่สิ่งเกิดขึ้น มาดูกันที่ Flag ต่างๆ

อีกสอง Flag ที่คุณจะใช้บ่อยๆ:

การรันที่คุณจะใช้บ่อยๆ มีลักษณะดังนี้:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users

แปดเธรด, 200 การเชื่อมต่อ, 30 วินาที, พร้อมกับการแสดงผลการกระจาย Latency เต็มรูปแบบในตอนท้าย

การอ่านผลลัพธ์

wrk จะพิมพ์รายงานสรุปออกมา นี่คือตัวอย่างการรันจริงกับบริการขนาดเล็ก:

Running 5s test @ http://10.135.232.163:3000
  2 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.82ms    2.64ms  26.68ms   85.81%
    Req/Sec   550.90    202.40     0.98k    68.00%
  5494 requests in 5.01s, 1.05MB read
Requests/sec:   1096.54
Transfer/sec:    215.24KB

อ่านจากล่างขึ้นบน เพราะสองบรรทัดสุดท้ายคือหัวข้อหลัก

Requests/sec คือ Throughput: จำนวน Requests ที่เซิร์ฟเวอร์ทำเสร็จต่อวินาทีโดยเฉลี่ย ในที่นี้คือ 1,096 นี่คือตัวเลขที่คุณจะใช้เปรียบเทียบระหว่างการรันและระหว่างการเปลี่ยนแปลงโค้ด

Transfer/sec คือ Bandwidth: จำนวนข้อมูลที่ถ่ายโอนต่อวินาที มีประโยชน์เมื่อ Payload มีขนาดใหญ่ หรือเมื่อคุณสงสัยว่าติดขัดที่ Bandwidth ไม่ใช่ CPU

มาดูตาราง Thread Stats ซึ่งอธิบายการกระจายตัว ไม่ใช่แค่ค่าเฉลี่ย:

คอลัมน์ +/- Stdev บอกคุณว่าเปอร์เซ็นต์ของตัวอย่างที่อยู่ในช่วง Standard Deviation หนึ่งๆ เป็นเท่าใด เปอร์เซ็นต์ที่ต่ำลงหมายถึงการกระจายตัวที่กว้างขึ้นและคาดเดาได้น้อยลง

บรรทัด 5494 requests in 5.01s ยืนยันปริมาณรวมที่การรันได้ส่งไปจริง

เมื่อคุณเพิ่ม --latency, wrk จะพิมพ์บล็อก Percentile เพื่อให้คุณเห็น Tail ได้โดยตรง:

  Latency Distribution
     50%    3.21ms
     75%    4.86ms
     90%    7.09ms
     99%   14.13ms

เปอร์เซ็นไทล์ที่ 99 เป็นตัวเลขที่ต้องจับตาดู หาก 99% ของ Requests เสร็จสิ้นภายใน 14ms แต่ค่าเฉลี่ยของคุณคือ 3.82ms นั่นหมายความว่าผู้ใช้หนึ่งในร้อยกำลังรอนานกว่าที่ค่าเฉลี่ยแนะนำมาก ค่าเฉลี่ยอาจบิดเบือนข้อมูลเกี่ยวกับ Tail ได้ แต่เปอร์เซ็นไทล์ไม่บิดเบือน

การส่ง POST Requests และ Custom Headers ด้วย Lua Script

โดยค่าเริ่มต้น wrk จะส่ง GET Requests หากต้องการส่ง POST, เพิ่ม Body, หรือตั้งค่า Custom Headers คุณต้องส่ง Lua Script ด้วย -s

สร้างไฟล์ชื่อ post.lua:

wrk.method = "POST"
wrk.body   = '{"name": "Ada", "role": "engineer"}'
wrk.headers["Content-Type"] = "application/json"

สามฟิลด์นี้ทำหน้าที่ wrk.method กำหนด HTTP Verb wrk.body กำหนด Request Body wrk.headers คือตารางที่ Key แต่ละตัวเป็นชื่อ Header

รันโดยชี้ -s ไปยัง Script:

wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/users

สำหรับการส่ง POST แบบ Form-Encoded แทน JSON, wrk repo มีตัวอย่างที่ตรงกันดังนี้:

wrk.method = "POST"
wrk.body   = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

คุณยังสามารถตั้งค่า Headers ด้วย Flag -H สำหรับกรณีที่ง่ายกว่า โดยไม่ต้องใช้ Script:

wrk -t4 -c100 -d30s -H "Authorization: Bearer TOKEN123" --latency http://localhost:3000/api/protected

ใช้ -H สำหรับหนึ่งหรือสอง Header ใช้ Lua Script เมื่อคุณต้องการ Body, Method ที่ไม่ใช่ GET, หรือ Logic ที่เฉพาะเจาะจงสำหรับแต่ละ Request

ข้อจำกัด: wrk ไม่ตรวจสอบความถูกต้อง

นี่คือส่วนที่คนมักพลาด wrk บอกคุณว่าเซิร์ฟเวอร์ตอบกลับเร็วแค่ไหน ไม่ได้บอกคุณว่าคำตอบนั้นถูกต้องหรือไม่

ลองชี้ wrk ไปยัง Endpoint ที่คืนค่า HTTP 500 สำหรับทุก Request คุณจะได้รายงานที่ดูดีพร้อมกับตัวเลข Requests-per-second ที่สูง wrk นับการแลกเปลี่ยน HTTP ที่เสร็จสมบูรณ์ ไม่ได้ยืนยัน Status Code, ตรวจสอบ Response Body กับ Schema, หรือยืนยันว่า API ทำงานตามที่ควรจะเป็น ข้อผิดพลาดก็อาจดูเหมือนเร็วได้ เพราะเซิร์ฟเวอร์ที่ปฏิเสธ Requests ตั้งแต่เนิ่นๆ จะทำงานน้อยลงต่อ Request

ดังนั้น wrk จึงตอบคำถามว่า "มันเร็วพอภายใต้โหลดหรือไม่?" แต่ไม่สามารถตอบคำถามว่า "มันถูกต้องหรือไม่?" ทั้งสองคำถามมีความสำคัญและต้องใช้เครื่องมือที่แตกต่างกัน ตัวเลขโหลดบน Endpoint ที่เสียคือตัวเลขที่คุณไม่ควรเชื่อ นี่คือเหตุผลว่าทำไมทีมจึงจับคู่เครื่องมือ Benchmarking เข้ากับ ชุดทดสอบ Functional อย่างแม่นยำ เครื่องมือหนึ่งพิสูจน์ความเร็ว อีกเครื่องมือหนึ่งพิสูจน์พฤติกรรม

Apidog และ Functional Testing เข้ากันได้ดีอย่างไร

Workflow ที่สะอาดคือสองชั้น ทำงานตามลำดับ

ขั้นแรก ตรวจสอบพฤติกรรม ก่อนที่คุณจะสนใจว่า Endpoint เร็วแค่ไหน ให้ยืนยันว่ามันถูกต้อง ใน Apidog คุณสร้างสถานการณ์ทดสอบที่ส่ง Request จริงและยืนยันสิ่งที่ส่งกลับมา: Status Code, ฟิลด์ JSON, Response Schema และ Business Logic คุณสามารถเชื่อมโยง Requests, ส่งข้อมูลระหว่างขั้นตอน และรันสถานการณ์เดียวกันในสภาพแวดล้อมต่างๆ นี่คือชั้นที่ตรวจจับข้อผิดพลาด 500 ที่ wrk ตรวจสอบประสิทธิภาพอย่างมีความสุข

จากนั้น ทดสอบประสิทธิภาพ (Benchmark Throughput) เมื่อพฤติกรรมได้รับการยืนยันแล้ว ให้รัน wrk กับ Endpoint เดียวกันเพื่อดูว่ามันรองรับ Concurrency และโหลดที่ต่อเนื่องได้อย่างไร Apidog ยังมี เครื่องมือทดสอบประสิทธิภาพในตัว หากคุณต้องการรวมงาน Functional และ Load ไว้ในที่เดียว แต่ wrk เป็นเครื่องมือเฉพาะที่ดีสำหรับการทดสอบประสิทธิภาพจาก Command-line โดยตรง

ชั้น Functional ทำงานใน CI ไม่ใช่แค่บนแล็ปท็อปของคุณ Apidog CLI เป็นแบบ Headless ดังนั้นจึงสามารถใส่ลงในขั้นตอน Pipeline ใดๆ ที่สามารถรัน Node ได้ ติดตั้งได้เลย:

npm install -g apidog-cli

จากนั้นรันสถานการณ์ทดสอบหรือ Suite ที่บันทึกไว้โดยใช้ ID:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,html,junit

-t คือ Scenario, Folder, หรือ Suite ID ที่จะรัน -e คือ Environment ID -r เลือกรูปแบบรายงาน หนึ่งหรือหลายรูปแบบจาก cli, html, json, และ junit เอาต์พุต JUnit สามารถเชื่อมต่อกับระบบ CI ส่วนใหญ่เพื่อกำหนดเกณฑ์ Pass/Fail สำหรับการรันที่ขับเคลื่อนด้วยข้อมูล ให้เพิ่ม -d (หรือ --iteration-data) พร้อมกับ File Path หรือ Test-Data ID เพื่อทำซ้ำ Scenario เดิมกับ Input หลายรายการ

CLI รัน Apidog Scenarios และ Suites ที่บันทึกไว้ มันเป็นแบบ Headless ไม่ใช่ Interactive Request Sender และไม่ใช่ Load Generator มันคือประตูการตรวจสอบความถูกต้อง wrk คือมาตรวัดความเร็ว รันประตูการตรวจสอบความถูกต้องใน Pipeline ของคุณ (ดู คำแนะนำ CLI CI/CD นี้ หรือ คู่มือ GitHub Actions สำหรับการคัดลอกและวางการตั้งค่า) จากนั้นทดสอบประสิทธิภาพด้วย wrk เมื่อคุณต้องการตัวเลข Throughput การอ้างอิง CLI ฉบับเต็ม ครอบคลุม Flag ที่เหลือ

คำถามที่พบบ่อย

wrk กับ ab (ApacheBench) ต่างกันอย่างไร? ทั้งคู่ส่งโหลด HTTP และรายงาน Requests ต่อวินาที wrk เป็นแบบ Multithreaded และใช้ Event Loop ดังนั้นจึงสามารถสร้างโหลดได้มากขึ้นจากเครื่องเดียวและจัดการ Concurrency สูงได้ดีกว่า ab เป็นแบบ Single-threaded สำหรับโหลดที่หนักจากเครื่องเดียว wrk มักจะรองรับได้ดีกว่า ไม่มีตัวใดตัวหนึ่งที่ตรวจสอบความถูกต้องของ Response

ฉันควรใช้จำนวนเธรดและการเชื่อมต่อเท่าไหร่? เริ่มต้นด้วยหนึ่งเธรดต่อหนึ่ง Core ของ CPU และตั้งค่าการเชื่อมต่อให้เท่ากับระดับ Concurrency ที่คุณต้องการจำลอง หากคุณมี 8 Core และต้องการจำลองไคลเอนต์พร้อมกัน 200 ราย ลองใช้ -t8 -c200 สังเกตเครื่องไคลเอนต์ หาก wrk เองติดขัดที่ CPU ตัวเลขของคุณจะสะท้อนถึงขีดจำกัดของ Load Generator ไม่ใช่ของเซิร์ฟเวอร์ เพิ่มการเชื่อมต่อขึ้นเรื่อยๆ จนกว่า Throughput จะหยุดเพิ่มขึ้น

wrk สามารถทดสอบ HTTPS Endpoints ได้หรือไม่? ได้ ชี้ไปที่ URL ที่เป็น https:// และ wrk จะจัดการ TLS นั่นคือเหตุผลที่ Linux Build ต้องการ libssl-dev การจับมือ TLS เพิ่มต้นทุน CPU ทั้งสองฝั่ง ดังนั้นคาดหวังว่า Throughput ดิบจะต่ำกว่าเมื่อเทียบกับ HTTP ธรรมดา

wrk ตรวจสอบ Response Body หรือ Status Code หรือไม่? ไม่ wrk นับการแลกเปลี่ยน HTTP ที่เสร็จสมบูรณ์และวัดเวลา ไม่ได้ยืนยัน Status Code หรือ Body ดังนั้น Endpoint ที่คืนค่าข้อผิดพลาดก็ยังสามารถแสดงตัวเลข Requests-per-second ที่สูงได้ ใช้ชุดทดสอบ Functional เช่นที่รันผ่าน Apidog CLI เพื่อตรวจสอบความถูกต้อง จากนั้นใช้ wrk สำหรับ Throughput

ควรใช้เวลานานเท่าไรในการทดสอบโหลด? นานพอที่จะผ่านผลกระทบจากการ Warm-up เช่น Cache ที่ยังไม่ทำงานเต็มที่และการ Compile แบบ JIT ไม่กี่วินาทีก็เพียงพอสำหรับการตรวจสอบอย่างรวดเร็ว แต่ 30 วินาทีถึงสองสามนาทีจะให้ตัวเลขที่เสถียรมากขึ้นและแสดงการลดลงของประสิทธิภาพที่เกิดขึ้นภายใต้โหลดที่ต่อเนื่องเท่านั้น ใช้ -d30s เป็นค่าเริ่มต้นที่ดี และยืดเวลาออกไปเมื่อคุณกำลังไล่ล่าหาข้อผิดพลาดที่เกิดขึ้นช้าๆ

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API