wrk: كيفية اختبار تحميل API من سطر الأوامر
ما هو wrk ومتى تستخدمه
wrk أداة اختبار أداء HTTP حديثة. تعمل من جهاز واحد متعدد الأنوية، وتستخدم الخيوط المتعددة مع حلقة أحداث قابلة للتوسع مثل epoll على Linux و kqueue على macOS. النتيجة: يمكنك توليد حمل كبير بدون إعداد أسطول من أجهزة الاختبار.
استخدم wrk عندما تريد إجابات مباشرة عن أسئلة مثل:
- كم طلبًا في الثانية تتحمل نقطة النهاية؟
- كيف يبدو زمن الاستجابة عند المتوسط، وخصوصًا عند الذيل مثل p99؟
- هل يبقى الأداء ثابتًا بعد 30 ثانية أو دقيقتين من الحمل؟
- هل المشكلة في الخادم أم في عرض النطاق أو قاعدة البيانات؟
لكن انتبه: wrk أداة قياس أداء، وليست أداة تحقق وظيفي. هي لا تتحقق من صحة JSON، ولا تتأكد من أن رمز الحالة 200، ولا تختبر عقد API. إذا أردت خلفية أوسع، راجع دليل اختبار تحميل API.
تثبيت wrk
macOS
أسهل طريقة هي Homebrew:
brew install wrk
على Apple Silicon، هذا الخيار مفضل لأن البناء من المصدر قد يواجه مشاكل متعلقة بـ LuaJIT وARM64.
لينكس: البناء من المصدر
ثبّت الأدوات المطلوبة أولًا:
sudo apt-get install build-essential libssl-dev git -y
ثم ابنِ الأداة:
git clone https://github.com/wg/wrk.git
cd wrk
make
بعدها انسخ الملف التنفيذي إلى مسار عام:
sudo cp wrk /usr/local/bin
وتأكد من التثبيت:
wrk --version
تشغيل أول اختبار
الصيغة الأساسية:
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
المعاني العملية للخيارات:
-tأو--threads: عدد خيوط التشغيل التي يستخدمها wrk. ابدأ غالبًا بخيط لكل نواة CPU.-cأو--connections: عدد اتصالات HTTP المفتوحة، أي مستوى التزامن الذي تريد محاكاته.-dأو--duration: مدة الاختبار مثل30sأو2mأو2h.
مثال عملي أكثر لنقطة API محلية:
wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
استخدم --latency في معظم الاختبارات لأنه يعرض نسب زمن الاستجابة مثل p50 و p90 و p99.
يمكنك أيضًا تحديد مهلة للطلبات:
wrk -t8 -c200 -d30s --latency --timeout 2s http://localhost:3000/api/users
هذا يجعل أي طلب لا يكتمل خلال ثانيتين يُسجل كمهلة، بدلًا من أن يشوه نتائج زمن الاستجابة.
قراءة مخرجات 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
اقرأ التقرير بهذا الترتيب:
1. Requests/sec
Requests/sec: 1096.54 هذا هو رقم الإنتاجية الأساسي: كم طلبًا مكتملًا في الثانية. استخدمه للمقارنة بين:
- إصدارين من الكود
- إعدادين مختلفين للخادم
- تشغيل قبل وبعد تحسين قاعدة البيانات
- HTTP مقابل HTTPS
2. Transfer/sec
Transfer/sec: 215.24KB هذا يوضح حجم البيانات المنقولة في الثانية. يصبح مهمًا عندما تكون الاستجابات كبيرة أو عندما تشك أن الاختناق في الشبكة.
3. Latency
Latency 3.82ms 2.64ms 26.68ms
هنا المتوسط 3.82ms، لكن الحد الأقصى 26.68ms. إذا كان الحد الأقصى بعيدًا جدًا عن المتوسط، فهذا يعني أن بعض الطلبات تعاني من بطء واضح حتى لو كانت معظم الطلبات سريعة.
4. Latency Distribution
عند استخدام --latency سترى شيئًا مثل:
Latency Distribution
50% 3.21ms
75% 4.86ms
90% 7.09ms
99% 14.13ms
راقب 99% أو p99. المتوسط وحده قد يخفي مشكلات الذيل. إذا كان المتوسط 3ms لكن p99 هو 200ms، فالمستخدمون سيشعرون بالتذبذب.
اختبار نقطة نهاية GET
ابدأ دائمًا بتشغيل بسيط لتثبيت خط الأساس:
wrk -t4 -c50 -d30s --latency http://localhost:3000/api/health
ثم ارفع التزامن تدريجيًا:
wrk -t4 -c100 -d30s --latency http://localhost:3000/api/health
wrk -t4 -c200 -d30s --latency http://localhost:3000/api/health
wrk -t4 -c400 -d30s --latency http://localhost:3000/api/health
راقب متى يحدث التالي:
- Requests/sec يتوقف عن الزيادة
- p99 يقفز فجأة
- تظهر أخطاء أو مهلات
- CPU أو الذاكرة أو قاعدة البيانات تصل إلى الحد الأقصى
هذه النقطة عادةً تكشف حد التحمل العملي لنقطة النهاية.
إرسال طلبات POST باستخدام Lua
افتراضيًا، يرسل wrk طلبات GET. لاختبار POST أو إرسال JSON أو ضبط رؤوس مخصصة، استخدم ملف Lua.
أنشئ ملفًا باسم post.lua:
wrk.method = "POST"
wrk.body = '{"name": "Ada", "role": "engineer"}'
wrk.headers["Content-Type"] = "application/json"
ثم شغّل الاختبار:
wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/users
إذا كانت نقطة النهاية تتطلب مصادقة:
wrk.method = "POST"
wrk.body = '{"name": "Ada", "role": "engineer"}'
wrk.headers["Content-Type"] = "application/json"
wrk.headers["Authorization"] = "Bearer TOKEN123"
ثم:
wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/users
لطلبات form-urlencoded:
wrk.method = "POST"
wrk.body = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
إضافة رؤوس بدون Lua
للحالات البسيطة، استخدم -H مباشرة:
wrk -t4 -c100 -d30s \
-H "Authorization: Bearer TOKEN123" \
--latency \
http://localhost:3000/api/protected
ولأكثر من رأس:
wrk -t4 -c100 -d30s \
-H "Authorization: Bearer TOKEN123" \
-H "Accept: application/json" \
--latency \
http://localhost:3000/api/protected
استخدم -H عندما تحتاج إلى رأس أو رأسين فقط. استخدم Lua عندما تحتاج إلى:
- POST أو PUT أو PATCH
- body مخصص
- منطق لكل طلب
- توليد بيانات ديناميكية
منهجية اختبار عملية
لا تبدأ مباشرة بـ -c1000. اتبع خطوات تصاعدية:
اختبر نقطة صحة بسيطة
wrk -t2 -c20 -d15s --latency http://localhost:3000/healthهذا يؤكد أن أداة الاختبار والخادم يعملان.
اختبر نقطة النهاية الحقيقية
wrk -t4 -c100 -d30s --latency http://localhost:3000/api/usersارفع التزامن تدريجيًا
wrk -t4 -c200 -d30s --latency http://localhost:3000/api/users wrk -t4 -c400 -d30s --latency http://localhost:3000/api/users wrk -t4 -c800 -d30s --latency http://localhost:3000/api/usersقارن الأرقام
أنشئ جدولًا بسيطًا:| الاتصالات | Requests/sec | p50 | p90 | p99 |
|-----------|-------------|-----|-----|-----|
| 100 | | | | |
| 200 | | | | |
| 400 | | | | |النقطة التي يبدأ عندها p99 بالقفز هي غالبًا أهم من أعلى رقم Requests/sec.
القيود: wrk لا يتحقق من صحة الاستجابة
هذه نقطة مهمة: wrk يخبرك أن الخادم رد بسرعة، لكنه لا يخبرك أن الرد صحيح. إذا كانت نقطة النهاية تُرجع HTTP 500 لكل طلب، قد تحصل على رقم Requests/sec مرتفع جدًا. السبب أن wrk يحسب تبادل HTTP مكتملًا، ولا يتحقق من:
- رمز الحالة
- بنية JSON
- مخطط الاستجابة
- منطق العمل
- تحقق قاعدة البيانات أن العملية حدثت فعلًا
لذلك لا تعتمد على wrk وحده. استخدمه للإجابة عن سؤال: هل الأداء كافٍ تحت الحمل؟ ولا تستخدمه للإجابة عن سؤال: هل الـ API تعمل بشكل صحيح؟ لهذا تستخدم الفرق عادةً أداة أداء مثل wrk مع مجموعة اختبارات وظيفية.
أين يدخل Apidog في سير العمل
سير العمل العملي يتكون من طبقتين:
أولًا: تحقق من السلوك
قبل قياس الأداء، تأكد أن نقطة النهاية صحيحة. في Apidog يمكنك بناء سيناريوهات اختبار ترسل طلبات حقيقية وتتحقق من:
- رموز الحالة
- حقول JSON
- مخطط الاستجابة
- تسلسل الطلبات
- تمرير البيانات بين الخطوات
- التشغيل عبر بيئات مختلفة
هذه الطبقة تلتقط الأخطاء التي لا يراها wrk.
ثانيًا: قِس الأداء
بعد نجاح الاختبارات الوظيفية، شغّل wrk ضد نفس نقاط النهاية:
wrk -t8 -c300 -d60s --latency https://api.example.com/users
إذا أردت الاحتفاظ بالاختبارات الوظيفية واختبارات الأداء داخل منصة واحدة، يوفر Apidog أيضًا اختبار أداء مدمج. أما wrk فهو خيار ممتاز عندما تريد قياسات سريعة من سطر الأوامر.
تشغيل اختبارات Apidog في CI
الاختبار الوظيفي يجب أن يعمل في CI، وليس فقط محليًا. يمكن تشغيل Apidog بدون واجهة رسومية عبر CLI.
ثبّت الواجهة:
npm install -g apidog-cli
ثم شغّل سيناريو أو مجموعة محفوظة:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
شرح الخيارات:
-t: معرف السيناريو أو المجلد أو المجموعة-e: معرف البيئة-r: تنسيقات التقرير مثلcliوhtmlوjsonوjunit
للتشغيل المعتمد على بيانات متعددة:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-d ./data.csv \
-r cli,junit
استخدم إخراج junit لدمج النتائج مع أنظمة CI.
الفكرة العملية: شغّل Apidog في CI للتحقق من صحة السلوك. إذا نجح، شغّل wrk في بيئة اختبار أداء لقياس الإنتاجية. لا تقبل رقم أداء لنقطة نهاية فاشلة وظيفيًا.
لإعدادات قابلة للنسخ، راجع دليل CLI CI/CD أو دليل GitHub Actions. كما يغطي مرجع CLI الكامل بقية الخيارات.
الأسئلة الشائعة
ما الفرق بين wrk و ab؟
كلاهما يرسل حمل HTTP ويعرض الطلبات في الثانية. لكن wrk متعدد الخيوط ويستخدم حلقة أحداث، لذلك يتعامل مع التزامن العالي بشكل أفضل من ab، الذي يكون أبسط وأقل قدرة على توليد حمل كبير من جهاز واحد. لا يتحقق أي منهما من صحة الاستجابة.
كم عدد الخيوط والاتصالات التي أستخدمها؟
ابدأ بخيط لكل نواة CPU تقريبًا. إذا كان لديك 8 أنوية وتريد محاكاة 200 اتصال متزامن:
wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
راقب جهاز توليد الحمل نفسه. إذا كان wrk يستهلك CPU بالكامل، فقد تكون تقيس حد جهاز الاختبار لا حد الخادم.
هل يدعم wrk HTTPS؟
نعم:
wrk -t4 -c100 -d30s --latency https://api.example.com/users
لكن TLS يضيف تكلفة CPU، لذلك قد ترى إنتاجية أقل من HTTP العادي.
هل يتحقق wrk من رمز الحالة؟
لا. wrk يقيس تبادلات HTTP المكتملة والتوقيت فقط. إذا كانت الاستجابة 500، سيستمر في عدّها ضمن النتائج. استخدم اختبارات وظيفية للتحقق من الصحة، ثم استخدم wrk للأداء.
كم يجب أن تستمر مدة الاختبار؟
للفحص السريع، 5 إلى 15 ثانية كافية. للأرقام الأكثر استقرارًا، استخدم 30 ثانية إلى عدة دقائق:
wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
زد المدة إذا كنت تبحث عن مشاكل تظهر تحت حمل طويل، مثل تسرب الذاكرة أو تدهور الأداء بعد الإحماء.
ما الرقم الأهم: المتوسط أم p99؟
راقب p99. المتوسط مفيد، لكنه يخفي الطلبات البطيئة. إذا كان p99 عاليًا، فجزء من المستخدمين سيشعر ببطء واضح حتى لو كان المتوسط جيدًا.
Comments
No comments yet. Start the discussion.