لقد أطلقت نقطة نهاية (endpoint) وتعمل في Postman. لكن السؤال العملي هو: ماذا يحدث عندما يرسل 200 عميل طلبات في الوقت نفسه؟ هل تتحمل 500 طلب/ثانية، أم يبدأ زمن الاستجابة بالتدهور عند 50؟ باستخدام ApacheBench يمكنك الحصول على قراءة سريعة بأمر واحد.
ApacheBench، أو الأمر ab، هو أداة سطر أوامر ترسل عددًا محددًا من طلبات HTTP إلى عنوان URL واحد، ثم تعرض الإنتاجية وزمن الاستجابة ونِسب التأخير. تأتي الأداة مع Apache HTTP Server، وهي مناسبة عندما تريد اختبار نقطة نهاية واحدة بسرعة قبل الانتقال إلى أدوات اختبار حمل أكثر تقدمًا.
في هذا الدليل ستتعلم كيف تثبّت ab، وتشغّل اختبار GET أساسيًا، وتختبر POST مع JSON، وتقرأ النتائج، وتعرف متى لا يكون ab الخيار المناسب. كل الأوامر تستخدم علامات موثقة في مرجع Apache ab الرسمي.
ما هو ApacheBench ومتى تستخدمه
ab هو عميل اختبار أداء بسيط. يفتح اتصالات نحو URL واحد، يرسل الطلبات حسب مستوى التزامن الذي تحدده، ثم يسجل زمن كل استجابة ويطبع ملخصًا.
استخدمه عندما تريد قياس:
- عدد الطلبات في الثانية لنقطة نهاية واحدة.
- متوسط زمن الاستجابة تحت حمل محدد.
- النسب المئوية مثل 95% و99% لمعرفة زمن استجابة الذيل.
- تأثير
Keep-Aliveعلى الأداء. - الفرق بين مستويات تزامن مختلفة مثل 10 و50 و100.
لا تستخدمه كبديل لاختبارات الوظائف أو السيناريوهات الكاملة. ab لا يتحقق من صحة JSON، ولا يراجع schema، ولا ينفذ تدفقات متعددة الخطوات مثل تسجيل الدخول ثم إنشاء مورد ثم قراءته. هو يرسل طلبًا واحدًا مرارًا ويقيس النتيجة.
لخلفية أوسع حول المجال، راجع ما هو اختبار حمل واجهة برمجة التطبيقات API load testing ولماذا يعتبر وقت استجابة واجهة برمجة التطبيقات API مهمًا.
تثبيت ab
يأتي ab ضمن أدوات Apache المساعدة، لكن اسم الحزمة يختلف حسب النظام.
على Debian وUbuntu:
sudo apt-get update
sudo apt-get install -y apache2-utils
على CentOS وRHEL وFedora:
# CentOS 7
sudo yum install -y httpd-tools
# Fedora و CentOS 8+
sudo dnf install -y httpd-tools
على macOS غالبًا يكون ab متاحًا مسبقًا لأن النظام يأتي مع Apache. تحقق من وجوده:
ab -V
إذا ظهر إصدار مثل Version 2.3 فأنت جاهز. إذا لم يكن الأمر موجودًا، ثبّت Apache عبر Homebrew ثم أعد التحقق.
تشغيل اختبار حمل أساسي
أهم علامتين في ab هما:
-
-n requests: العدد الإجمالي للطلبات. -
-c concurrency: عدد الطلبات المتزامنة.
مثال: إرسال 1000 طلب إلى نقطة نهاية JSON، مع 50 طلبًا متزامنًا:
ab -n 1000 -c 50 https://api.example.com/v1/users
انتبه إلى أن ab يحتاج URL كاملًا مع مسار. إذا كنت تختبر الجذر فاستخدم الشرطة المائلة في النهاية:
ab -n 1000 -c 50 https://api.example.com/
تفعيل Keep-Alive
العملاء الحقيقيون غالبًا يعيدون استخدام اتصالات TCP بدل فتح اتصال جديد لكل طلب. لتقريب الاختبار من هذا السلوك، أضف -k:
ab -n 1000 -c 50 -k https://api.example.com/v1/users
قارن نتيجة التشغيل بدون -k ومعها. إذا تحسن الأداء كثيرًا عند تفعيل Keep-Alive، فهذا يعني أن جزءًا مهمًا من زمن الاستجابة كان ناتجًا عن تكلفة إنشاء الاتصال.
تشغيل اختبار لمدة محددة
بدل تحديد عدد الطلبات فقط، يمكنك تحديد مدة الاختبار بالثواني باستخدام -t:
ab -t 30 -c 50 -k https://api.example.com/v1/users
هذا يشغّل الاختبار لمدة تصل إلى 30 ثانية عند تزامن 50. داخليًا، تفترض -t قيمة كبيرة لـ -n، ويتوقف الاختبار عند الوصول إلى الحد الزمني أو عدد الطلبات، أيهما يأتي أولًا.
اختبار نقطة نهاية POST
لاختبار POST، ضع جسم الطلب في ملف ثم مرره باستخدام -p. يجب أيضًا تحديد نوع المحتوى باستخدام -T.
أنشئ ملف الحمولة:
cat > payload.json <<'EOF'
{"name": "Ada Lovelace", "email": "ada@example.com"}
EOF
ثم شغّل الاختبار:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
https://api.example.com/v1/users
شرح العلامات:
-
-p payload.json: يرسل محتوى الملف كجسم طلب POST. -
-T application/json: يضبط رأسContent-Type. -
-n 500: يرسل 500 طلب إجمالًا. -
-c 25: يشغّل 25 طلبًا في الوقت نفسه. -
-k: يفعّلKeep-Alive.
إذا كانت نقطة النهاية تحتاج مصادقة، أضف رأس Authorization باستخدام -H:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/users
يمكنك تكرار -H لإضافة أكثر من رأس:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Request-Source: load-test" \
https://api.example.com/v1/users
إذا أردت مراجعة بناء JSON يدويًا، راجع كيفية إرسال بيانات JSON باستخدام curl. يمكنك استخدام نفس النص كملف حمولة في ab.
قراءة مخرجات ab
مثال مختصر لمخرجات ab:
Concurrency Level: 50
Time taken for tests: 4.212 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 0
Requests per second: 237.42 [#/sec] (mean)
Time per request: 210.598 [ms] (mean)
Time per request: 4.212 [ms] (mean, across all concurrent requests)
Transfer rate: 142.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 18 9.4 16 64
Processing: 22 189 41.2 182 310
Waiting: 21 177 39.8 171 295
Total: 31 207 42.7 201 338
Percentage of the requests served within a certain time (ms)
50% 201
66% 221
75% 236
90% 268
95% 291
99% 324
100% 338 (longest request)
ابدأ بهذه الحقول:
- Requests per second: الإنتاجية. هذا هو عدد الطلبات التي عالجتها نقطة النهاية في الثانية.
-
Failed requests: الطلبات التي اعتبرها
abفاشلة. - Non-2xx responses: الاستجابات التي لم تكن من فئة 2xx.
- Time per request: يظهر مرتين. السطر الأول هو الزمن الذي يشعر به المستخدم تقريبًا. السطر الثاني هو المتوسط عبر كل الطلبات المتزامنة، وليس الرقم الذي تركز عليه عادة لتجربة المستخدم.
- Percentage of the requests served within a certain time: أهم جزء لفهم زمن الاستجابة عند النسب المئوية.
في المثال:
- 50% من الطلبات انتهت خلال 201ms.
- 95% انتهت خلال 291ms.
- 99% انتهت خلال 324ms.
- أبطأ طلب استغرق 338ms.
راقب 95% و99% أكثر من المتوسط، لأن مشاكل الأداء تظهر غالبًا في الذيل لا في المتوسط.
تصدير النتائج
للحصول على ملف CSV بالنسب المئوية:
ab -n 1000 -c 50 -k -e results.csv https://api.example.com/v1/users
ولإخراج ملف مناسب لـ gnuplot:
ab -n 1000 -c 50 -k -g results.tsv https://api.example.com/v1/users
طريقة عملية لاختيار قيم n و c
لا تبدأ مباشرة بتزامن عالٍ. اختبر تدريجيًا:
ab -n 1000 -c 10 -k https://api.example.com/v1/users
ab -n 1000 -c 25 -k https://api.example.com/v1/users
ab -n 1000 -c 50 -k https://api.example.com/v1/users
ab -n 1000 -c 100 -k https://api.example.com/v1/users
راقب في كل تشغيل:
- هل ترتفع
Requests per second؟ - هل تزيد
Failed requests؟ - هل تظهر
Non-2xx responses؟ - هل تقفز قيم 95% و99%؟
- هل يصل CPU أو قاعدة البيانات أو الشبكة إلى حد واضح؟
عندما تتوقف الإنتاجية عن الارتفاع وتبدأ الأخطاء أو زمن الذيل بالزيادة، تكون قد اقتربت من نقطة التشبع لهذه النقطة النهائية في ظروف الاختبار الحالية.
متى لا يكون ab الأداة المناسبة
ab مفيد، لكنه محدود عمدًا.
1. عنوان URL واحد لكل تشغيل
لا يستطيع ab تنفيذ رحلة مستخدم مثل:
- تسجيل الدخول.
- استخراج token.
- إنشاء مورد.
- قراءة المورد.
- تحديثه.
إذا احتجت هذا النوع من التدفقات، فأنت تحتاج أداة سيناريوهات.
2. لا يتحقق من صحة الاستجابة
ab لا يراجع أن JSON يحتوي الحقول الصحيحة، ولا يتحقق من schema، ولا يؤكد أن قيمة معينة تطابق المتوقع. إذا كانت الاستجابة HTTP 200 لكن الجسم خاطئ منطقيًا، قد تبدو النتيجة ناجحة من منظور الحمل.
3. لا يدعم HTTP/2
حسب الوثائق الرسمية، ab لا ينفذ HTTP/1.x بالكامل ولا يدعم HTTP/2. إذا كان أداء الخادم تحت HTTP/2 مهمًا لتطبيقك، استخدم أداة تدعم HTTP/2.
4. الحمل يأتي من جهاز واحد
ab يعمل من جهاز واحد وعملية واحدة. عند مستويات تزامن عالية جدًا، قد تقيس حدود جهاز الاختبار بدل حدود الخادم. راقب موارد الجهاز الذي يشغّل ab حتى لا تخلط بين عنق زجاجة العميل وعنق زجاجة الخادم.
عندما تحتاج تدفقات متعددة الخطوات أو تشغيلات موزعة، يمكن أن تكون أدوات مثل JMeter أكثر ملاءمة. وإذا كنت تقارن الخيارات، راجع مجموعة أوسع من أدوات اختبار الحمل.
أين يتناسب الاختبار الوظيفي
اختبار الحمل يجيب عن سؤال: هل نقطة النهاية سريعة بما يكفي تحت ضغط؟
لكن قبل ذلك تحتاج سؤالًا آخر: هل نقطة النهاية صحيحة أصلًا؟
هنا يأتي الاختبار الوظيفي واختبار العقد. قبل تشغيل ab، تأكد أن الاستجابة:
- ترجع status code صحيحًا.
- تحتوي JSON صالحًا.
- تطابق schema المتفق عليه.
- تحتوي القيم المتوقعة.
- تعمل ضمن سيناريوهات الاستخدام الحقيقية.
يمكن استخدام Apidog لبناء سيناريوهات اختبار مع تأكيدات مرئية، وربط الطلبات في تدفقات متعددة الخطوات، والتحقق من صحة الاستجابات مقابل schema. هذه مهام لا يحاول ab حلها.
لتشغيل السيناريوهات المحفوظة في 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. -
-dأو--iteration-data: يضيف بيانات تشغيل لاختبارات تعتمد على بيانات.
الاستخدام العملي يكون كالتالي:
- شغّل اختبارات Apidog للتأكد من صحة السلوك.
- شغّل
abلقياس الأداء تحت حمل محدد. - راقب الأخطاء، زمن الاستجابة، وقيم 95% و99%.
- كرر الاختبار بعد كل تحسين في الكود أو البنية التحتية.
لمزيد من التفاصيل، راجع دليل اختبار الأداء في Apidog والبرنامج التعليمي العام لاختبار أداء واجهة برمجة التطبيقات API.
الأسئلة الشائعة
هل ApacheBench مخصص لخوادم Apache فقط؟
لا. رغم الاسم، يرسل ab طلبات HTTP وHTTPS عادية إلى أي خادم. يمكنك استخدامه مع Nginx أو Node.js أو Go أو Python أو أي خدمة تتحدث HTTP. علاقته بـ Apache هي أنه يأتي ضمن أدوات Apache HTTP Server.
ما مستوى التزامن المناسب؟
ابدأ بقيمة منخفضة ثم ارفعها تدريجيًا:
ab -n 1000 -c 10 -k https://api.example.com/v1/users
ab -n 1000 -c 25 -k https://api.example.com/v1/users
ab -n 1000 -c 50 -k https://api.example.com/v1/users
اختر القيم بناءً على حركة المرور المتوقعة لا على رقم عشوائي كبير. الهدف هو معرفة نقطة التشبع الواقعية.
لماذا تظهر Failed requests رغم أن API تعمل؟
يصنف ab الطلب كفاشل أحيانًا إذا اختلف طول الاستجابة بين الطلبات، وهذا طبيعي في JSON الديناميكي. يمكنك إضافة -l حتى لا يحتسب اختلاف الطول كفشل:
ab -n 1000 -c 50 -k -l https://api.example.com/v1/users
بعد ذلك، راقب Non-2xx responses لمعرفة هل توجد أخطاء HTTP حقيقية.
هل يمكن لـ ab اختبار نقطة نهاية تحتاج token؟
نعم، إذا كان لديك token جاهز:
ab -n 500 -c 25 -k \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/users
لكن ab لا يستطيع تسجيل الدخول أولًا للحصول على token ثم استخدامه في طلب لاحق. هذا تدفق متعدد الخطوات ويحتاج أداة سيناريوهات.
هل يدعم ab بروتوكول HTTP/2؟
لا. ab يعمل مع HTTP/1.x ولا يدعم HTTP/2. إذا كان أداء HTTP/2 جزءًا مهمًا من نظامك، استخدم أداة اختبار حمل تدعم HTTP/2.

Top comments (0)