DEV Community

Cover image for ApacheBench (ab): كيفية اختبار تحميل API من سطر الأوامر
Yusuf Khalidd
Yusuf Khalidd

Posted on • Originally published at apidog.com

ApacheBench (ab): كيفية اختبار تحميل API من سطر الأوامر

لقد أطلقت نقطة نهاية (endpoint) وتعمل في Postman. لكن السؤال العملي هو: ماذا يحدث عندما يرسل 200 عميل طلبات في الوقت نفسه؟ هل تتحمل 500 طلب/ثانية، أم يبدأ زمن الاستجابة بالتدهور عند 50؟ باستخدام ApacheBench يمكنك الحصول على قراءة سريعة بأمر واحد.

جرّب Apidog اليوم

ApacheBench، أو الأمر ab، هو أداة سطر أوامر ترسل عددًا محددًا من طلبات HTTP إلى عنوان URL واحد، ثم تعرض الإنتاجية وزمن الاستجابة ونِسب التأخير. تأتي الأداة مع Apache HTTP Server، وهي مناسبة عندما تريد اختبار نقطة نهاية واحدة بسرعة قبل الانتقال إلى أدوات اختبار حمل أكثر تقدمًا.

في هذا الدليل ستتعلم كيف تثبّت ab، وتشغّل اختبار GET أساسيًا، وتختبر POST مع JSON، وتقرأ النتائج، وتعرف متى لا يكون ab الخيار المناسب. كل الأوامر تستخدم علامات موثقة في مرجع Apache ab الرسمي.

ما هو ApacheBench ومتى تستخدمه

ab هو عميل اختبار أداء بسيط. يفتح اتصالات نحو URL واحد، يرسل الطلبات حسب مستوى التزامن الذي تحدده، ثم يسجل زمن كل استجابة ويطبع ملخصًا.

ApacheBench

استخدمه عندما تريد قياس:

  • عدد الطلبات في الثانية لنقطة نهاية واحدة.
  • متوسط زمن الاستجابة تحت حمل محدد.
  • النسب المئوية مثل 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
Enter fullscreen mode Exit fullscreen mode

على CentOS وRHEL وFedora:

# CentOS 7
sudo yum install -y httpd-tools

# Fedora و CentOS 8+
sudo dnf install -y httpd-tools
Enter fullscreen mode Exit fullscreen mode

على macOS غالبًا يكون ab متاحًا مسبقًا لأن النظام يأتي مع Apache. تحقق من وجوده:

ab -V
Enter fullscreen mode Exit fullscreen mode

إذا ظهر إصدار مثل Version 2.3 فأنت جاهز. إذا لم يكن الأمر موجودًا، ثبّت Apache عبر Homebrew ثم أعد التحقق.

تشغيل اختبار حمل أساسي

أهم علامتين في ab هما:

  • -n requests: العدد الإجمالي للطلبات.
  • -c concurrency: عدد الطلبات المتزامنة.

مثال: إرسال 1000 طلب إلى نقطة نهاية JSON، مع 50 طلبًا متزامنًا:

ab -n 1000 -c 50 https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

انتبه إلى أن ab يحتاج URL كاملًا مع مسار. إذا كنت تختبر الجذر فاستخدم الشرطة المائلة في النهاية:

ab -n 1000 -c 50 https://api.example.com/
Enter fullscreen mode Exit fullscreen mode

تفعيل Keep-Alive

العملاء الحقيقيون غالبًا يعيدون استخدام اتصالات TCP بدل فتح اتصال جديد لكل طلب. لتقريب الاختبار من هذا السلوك، أضف -k:

ab -n 1000 -c 50 -k https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

قارن نتيجة التشغيل بدون -k ومعها. إذا تحسن الأداء كثيرًا عند تفعيل Keep-Alive، فهذا يعني أن جزءًا مهمًا من زمن الاستجابة كان ناتجًا عن تكلفة إنشاء الاتصال.

تشغيل اختبار لمدة محددة

بدل تحديد عدد الطلبات فقط، يمكنك تحديد مدة الاختبار بالثواني باستخدام -t:

ab -t 30 -c 50 -k https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

هذا يشغّل الاختبار لمدة تصل إلى 30 ثانية عند تزامن 50. داخليًا، تفترض -t قيمة كبيرة لـ -n، ويتوقف الاختبار عند الوصول إلى الحد الزمني أو عدد الطلبات، أيهما يأتي أولًا.

اختبار نقطة نهاية POST

لاختبار POST، ضع جسم الطلب في ملف ثم مرره باستخدام -p. يجب أيضًا تحديد نوع المحتوى باستخدام -T.

أنشئ ملف الحمولة:

cat > payload.json <<'EOF'
{"name": "Ada Lovelace", "email": "ada@example.com"}
EOF
Enter fullscreen mode Exit fullscreen mode

ثم شغّل الاختبار:

ab -n 500 -c 25 -k \
  -p payload.json \
  -T application/json \
  https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

شرح العلامات:

  • -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
Enter fullscreen mode Exit fullscreen mode

يمكنك تكرار -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
Enter fullscreen mode Exit fullscreen mode

إذا أردت مراجعة بناء 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)
Enter fullscreen mode Exit fullscreen mode

ابدأ بهذه الحقول:

  • 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
Enter fullscreen mode Exit fullscreen mode

ولإخراج ملف مناسب لـ gnuplot:

ab -n 1000 -c 50 -k -g results.tsv https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

طريقة عملية لاختيار قيم 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
Enter fullscreen mode Exit fullscreen mode

راقب في كل تشغيل:

  1. هل ترتفع Requests per second؟
  2. هل تزيد Failed requests؟
  3. هل تظهر Non-2xx responses؟
  4. هل تقفز قيم 95% و99%؟
  5. هل يصل CPU أو قاعدة البيانات أو الشبكة إلى حد واضح؟

عندما تتوقف الإنتاجية عن الارتفاع وتبدأ الأخطاء أو زمن الذيل بالزيادة، تكون قد اقتربت من نقطة التشبع لهذه النقطة النهائية في ظروف الاختبار الحالية.

متى لا يكون ab الأداة المناسبة

ab مفيد، لكنه محدود عمدًا.

1. عنوان URL واحد لكل تشغيل

لا يستطيع ab تنفيذ رحلة مستخدم مثل:

  1. تسجيل الدخول.
  2. استخراج token.
  3. إنشاء مورد.
  4. قراءة المورد.
  5. تحديثه.

إذا احتجت هذا النوع من التدفقات، فأنت تحتاج أداة سيناريوهات.

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
Enter fullscreen mode Exit fullscreen mode

ثم شغّل سيناريو أو مجموعة اختبار محفوظة:

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

شرح سريع:

  • -t: يحدد سيناريو أو مجلدًا أو مجموعة اختبار محفوظة بالمعرف.
  • -e: يحدد البيئة.
  • -r: يحدد نوع التقرير مثل cli أو html أو json أو junit.
  • -d أو --iteration-data: يضيف بيانات تشغيل لاختبارات تعتمد على بيانات.

الاستخدام العملي يكون كالتالي:

  1. شغّل اختبارات Apidog للتأكد من صحة السلوك.
  2. شغّل ab لقياس الأداء تحت حمل محدد.
  3. راقب الأخطاء، زمن الاستجابة، وقيم 95% و99%.
  4. كرر الاختبار بعد كل تحسين في الكود أو البنية التحتية.

لمزيد من التفاصيل، راجع دليل اختبار الأداء في 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
Enter fullscreen mode Exit fullscreen mode

اختر القيم بناءً على حركة المرور المتوقعة لا على رقم عشوائي كبير. الهدف هو معرفة نقطة التشبع الواقعية.

لماذا تظهر Failed requests رغم أن API تعمل؟

يصنف ab الطلب كفاشل أحيانًا إذا اختلف طول الاستجابة بين الطلبات، وهذا طبيعي في JSON الديناميكي. يمكنك إضافة -l حتى لا يحتسب اختلاف الطول كفشل:

ab -n 1000 -c 50 -k -l https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

بعد ذلك، راقب Non-2xx responses لمعرفة هل توجد أخطاء HTTP حقيقية.

هل يمكن لـ ab اختبار نقطة نهاية تحتاج token؟

نعم، إذا كان لديك token جاهز:

ab -n 500 -c 25 -k \
  -H "Authorization: Bearer YOUR_TOKEN" \
  https://api.example.com/v1/users
Enter fullscreen mode Exit fullscreen mode

لكن ab لا يستطيع تسجيل الدخول أولًا للحصول على token ثم استخدامه في طلب لاحق. هذا تدفق متعدد الخطوات ويحتاج أداة سيناريوهات.

هل يدعم ab بروتوكول HTTP/2؟

لا. ab يعمل مع HTTP/1.x ولا يدعم HTTP/2. إذا كان أداء HTTP/2 جزءًا مهمًا من نظامك، استخدم أداة اختبار حمل تدعم HTTP/2.

Top comments (0)