لقد أطلقت نقطة نهاية (endpoint). تعيد استجابة JSON الصحيحة في Postman. ولكن ليس لديك أي فكرة عما يحدث عندما يضربها 200 عميل في وقت واحد. هل تتحمل 500 طلب في الثانية، أم تتدهور زمن الاستجابة عند 50؟ يجيب ApacheBench على هذا السؤال في أمر واحد.
ApacheBench، الذي يُستدعى باسم ab، هو أداة سطر أوامر ترسل عددًا ثابتًا من طلبات HTTP إلى عنوان URL واحد وتقدم تقارير عن الإنتاجية وزمن الاستجابة. يأتي مع خادم Apache HTTP Server وهو موجود منذ عقود. إنه صغير، وسريع التشغيل، ويمنحك قراءة سريعة حول مقدار الحمل الذي يمكن أن تتحمله نقطة نهاية واحدة.
يغطي هذا الدليل تثبيت ab، وتشغيل اختبار أساسي، واختبار نقاط نهاية POST، وقراءة المخرجات، ومعرفة متى يتوقف ab عن كونه الأداة المناسبة. كل أمر هنا يتوافق مع علامة موثقة في مرجع Apache ab الرسمي.
ما هو ApacheBench ومن أين يأتي
ab هو عميل اختبار أداء مدمج مع خادم Apache HTTP Server. الاسم هو اختصار لـ ApacheBench. يفتح اتصالات بعنوان URL واحد، ويرسل الطلبات بأقصى سرعة تسمح بها إعدادات التزامن لديك، ويسجل وقت كل استجابة، ويطبع ملخصًا.

إنه يقيس شيئًا واحدًا جيدًا: عدد الطلبات في الثانية التي يمكن أن تخدمها نقطة نهاية واحدة، وكيفية توزيع وقت الاستجابة تحت الحمل. هذه هي الإنتاجية وزمن الاستجابة لعنوان URL واحد.
ما لا يفعله لا يقل أهمية. لا يتحقق ab مما إذا كان نص الاستجابة صحيحًا. لا يتحقق من مخطط (schema) أو يؤكد على حقل. لا يتبع تدفقًا متعدد الخطوات مثل تسجيل الدخول، ثم الجلب، ثم التحديث. إنه يضرب عنوان URL واحدًا ويعد. ضع هذا النطاق في الاعتبار وسيظل ab مفيدًا. توقع المزيد وستصاب بخيبة أمل.
إذا كنت تريد رؤية أوسع للمجال الذي يناسبه ab، فراجع ما هو اختبار حمل واجهة برمجة التطبيقات (API load testing) ولماذا يعتبر وقت استجابة واجهة برمجة التطبيقات (API) مهمًا.
تثبيت ab
يأتي ab مدمجًا مع أدوات Apache المساعدة. يختلف اسم الحزمة حسب النظام الأساسي.
على Debian و Ubuntu، قم بتثبيت حزمة apache2-utils:
sudo apt-get update
sudo apt-get install -y apache2-utils
على CentOS و RHEL و Fedora، الحزمة هي httpd-tools:
# CentOS 7
sudo yum install -y httpd-tools
# Fedora and CentOS 8+
sudo dnf install -y httpd-tools
على macOS، ab موجود بالفعل لأن النظام يأتي مع Apache. تحقق من ذلك:
ab -V
يجب أن ترى سطر إصدار مثل Version 2.3. إذا كان الأمر مفقودًا على macOS، قم بتثبيته عبر صيغة Apache في Homebrew. بمجرد أن يطبع ab -V إصدارًا، فأنت جاهز.
تشغيل اختبار حمل أساسي
العلامتان اللتان ستستخدمهما في كل مرة هما -n و -c.
-n requestsتحدد العدد الإجمالي للطلبات التي سيتم إجراؤها. الإعداد الافتراضي هو طلب واحد، والذي لا يخبرك بشيء، لذا اضبط هذا دائمًا.-c concurrencyتحدد عدد الطلبات التي تعمل في نفس الوقت. الإعداد الافتراضي هو واحد، مما يعني تسلسلي بالكامل.
إليك 1000 طلب، 50 في كل مرة، مقابل نقطة نهاية JSON:
ab -n 1000 -c 50 https://api.example.com/v1/users
لاحظ المسار اللاحق. يحتاج ab إلى عنوان URL كامل مع مسار. إذا وجهته إلى مضيف بدون مسار، فسيحدث خطأ. للجذر، استخدم شرطة مائلة لاحقة: https://api.example.com/.
يعيد العملاء الحقيقيون استخدام اتصالات TCP بدلاً من فتح اتصال جديد لكل طلب. أضف -k لتمكين HTTP KeepAlive بحيث يعيد ab استخدام الاتصالات داخل الجلسة:
ab -n 1000 -c 50 -k https://api.example.com/v1/users
عادةً ما يكون التشغيل باستخدام -k أقرب إلى كيفية تصرف المتصفح أو عميل واجهة برمجة التطبيقات (API) جيد التصرف، لأنه يتجنب دفع تكلفة إعداد الاتصال في كل طلب. قارن الرقمين لترى مقدار زمن الاستجابة لديك هو تكلفة الاتصال الزائدة.
يمكنك أيضًا تحديد مدة التشغيل بالوقت بدلاً من العدد. تحدد -t الحد الأقصى لعدد الثواني وتفترض ضمنيًا -n 50000 داخليًا، لذلك يتوقف الاختبار عند الحد الذي تصل إليه أولاً:
ab -t 30 -c 50 -k https://api.example.com/v1/users
يستغرق ذلك ما يصل إلى 30 ثانية بتزامن 50. مفيد عندما تريد قراءة بمدة محددة بدلاً من عدد ثابت.
اختبار نقطة نهاية POST
معظم أعمال واجهة برمجة التطبيقات (API) ليست طلبات GET. لاختبار طلب POST، ضع نص الطلب في ملف ومرره باستخدام -p. يجب عليك أيضًا تعيين نوع المحتوى باستخدام -T، وإلا سيرفض الخادم نص الطلب.
أنشئ حمولة البيانات (payload):
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 تحدد اسم الملف الذي يحتوي على نص طلب POST. العلامة -T تحدد رأس Content-Type. نوع المحتوى الافتراضي هو text/plain، وهو تقريبًا ليس ما تريده واجهة برمجة التطبيقات (API) التي تتعامل مع JSON، لذا اضبط -T application/json بشكل صريح.
إذا كانت نقطة النهاية الخاصة بك تحتاج إلى مصادقة أو رؤوس أخرى، فأضفها باستخدام -H. كرر العلامة لكل رأس:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/users
لتحديث معلوماتك حول بناء نصوص طلب JSON يدويًا، راجع كيفية إرسال بيانات JSON باستخدام curl. يعمل نفس النص كملف حمولة بيانات 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)
اقرأ هذه الحقول أولاً:
- الطلبات في الثانية هي عنوان إنتاجيتك الرئيسي. إنها عدد الطلبات مقسومًا على الوقت الإجمالي. كلما ارتفع الرقم كان أفضل.
- الطلبات الفاشلة والاستجابات غير 2xx تخبرك ما إذا كان الخادم قد تعامل مع الحمل بالفعل أو بدأ في إظهار الأخطاء. لا يعني الرقم المرتفع للطلبات في الثانية شيئًا إذا كان نصف الاستجابات من فئة 500s. تحقق دائمًا من هذين قبل أن تثق في رقم الإنتاجية.
- الوقت المستغرق لكل طلب يظهر مرتين. السطر الأول هو متوسط الوقت الذي ينتظره المستخدم الواحد (التزامن مضروبًا في الوقت الإجمالي مقسومًا على الطلبات). السطر الثاني، الذي يحمل تسمية "عبر جميع الطلبات المتزامنة"، هو متوسط الفجوة بين الطلبات المكتملة. الرقم الأول هو ما يشعر به المستخدمون.
جدول النسبة المئوية للطلبات التي تم تقديمها خلال وقت معين هو الجزء الأكثر فائدة. إنه تحليل حسب النسبة المئوية. الصف 50% هو الوسيط الخاص بك. تُظهر الصفوف 95% و 99% الذيل البطيء. في المثال، انتهى نصف الطلبات بحلول 201 مللي ثانية، لكن 1% استغرقت 324 مللي ثانية أو أكثر. زمن استجابة الذيل هو المكان الذي يتأثر فيه المستخدمون الحقيقيون، لذا راقب النسب المئوية 95 و 99 أكثر من المتوسط.
هل تريد الأرقام الخام لكل طلب من أجل رسم بياني؟ أضف -e results.csv لكتابة ملف CSV من أزواج النسبة المئوية إلى الوقت، أو -g results.tsv لملف متوافق مع gnuplot.
متى يتوقف ab عن كونه الأداة المناسبة
ab ضيق النطاق عمدًا. من الجدير ذكر حدوده بوضوح حتى لا تسيء استخدامه.
- عنوان URL واحد لكل تشغيل. يضغط
abعلى نقطة نهاية واحدة. لا يمكنه برمجة تسلسل مثل المصادقة، وإنشاء مورد، ثم قراءته. تتطلب رحلات المستخدم الحقيقية لمس العديد من نقاط النهاية بالترتيب، وabليس لديه أي مفهوم لذلك. - لا توجد فحوصات صحة. يحسب
abرموز الحالة وأطوال البايت. لا يقوم بتحليل JSON الخاص بك أو التأكيد على أن حقلًا يساوي قيمة متوقعة. يمكن أن تكون الاستجابة خاطئة من الناحية الهيكلية وما زالت تعتبر نجاحًا. أرقام التحميل ليست بديلاً لمجموعة اختبار ناجحة. - معالجة HTTP قديمة. تنص الوثائق الرسمية على أن
abلا ينفذ HTTP/1.x بالكامل ويقبل فقط بعض أشكال الاستجابات المتوقعة. لا يدعم HTTP/2. بالنسبة للخوادم التي تتصرف بشكل مختلف تحت HTTP/2، لن يعكسabذلك. - حمل جهاز واحد. يعمل
abمن جهاز واحد وعملية واحدة. بعد تزامن معين، ستقيس حدود العميل الخاص بك بدلاً من حدود الخادم. تحذر الوثائق حتى من أن تحليلabالخاص يمكن أن يظهر كعائق في ملفات التعريف (profiles).
لا شيء من هذا يجعل ab سيئًا. بل يجعله أداة محددة: مسبار سريع للإنتاجية لنقطة نهاية واحدة. عندما تحتاج إلى تدفقات مبرمجة، أو حمل موزع، أو HTTP/2، ابحث عن أداة مصممة لذلك. يتعامل JMeter مع السيناريوهات متعددة الخطوات والتشغيلات الموزعة، وهناك مجموعة أوسع من أدوات اختبار الحمل إذا كنت تقارن الخيارات.
أين يتناسب الاختبار الوظيفي
الإنتاجية هي محور واحد. والصحة هي محور آخر، ولا يتطرق ab إليها. قبل أن تختبر حمل نقطة نهاية، تريد أن تعرف أنها تُعيد البيانات الصحيحة بالشكل الصحيح في الظروف العادية. هذا هو الاختبار الوظيفي واختبار العقد، وهي مهمة مختلفة.
هنا تكتسب منصة API الكاملة مكانها بجانب ab. يتيح لك Apidog بناء سيناريوهات اختبار مع تأكيدات مرئية، وربط الطلبات في تدفقات متعددة الخطوات، والتحقق من صحة الاستجابات مقابل المخطط الخاص بك، وهي الأشياء التي لا يستطيع ab القيام بها حسب تصميمه. يمكنك حفظ تلك السيناريوهات مرة واحدة وتشغيلها في أي مكان.
للتكامل المستمر، يقوم Apidog CLI بتشغيل السيناريوهات المحفوظة بدون واجهة رسومية. قم بتثبيته باستخدام Node:
npm install -g apidog-cli
ثم قم بتشغيل سيناريو محفوظ أو مجموعة اختبار مقابل بيئة مختارة، مع إصدار تقارير يمكن لأداة التكامل المستمر (CI) الخاصة بك أرشفتها:
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) مع مسار ملف بيانات أو معرف بيانات الاختبار. CLI يعمل بدون واجهة رسومية ويقوم بتشغيل السيناريوهات المحفوظة، لذا فهو يناسب أي خطوة CI يمكنها تشغيل Node. إنه ليس مرسل طلبات وليس مولد حمل، بل يقوم بتشغيل الاختبارات الوظيفية التي لم يكن ab مخصصًا لتشغيلها.
الإعداد السليم يستخدم كليهما. قم بتشغيل سيناريوهات Apidog لإثبات صحة نقطة النهاية. قم بتشغيل ab لإثبات أنها سريعة بما فيه الكفاية. فيما يتعلق بالصحة، راجع دليل اختبار الأداء في Apidog والبرنامج التعليمي العام لاختبار أداء واجهة برمجة التطبيقات (API).
الأسئلة الشائعة
هل ApacheBench مخصص لخوادم Apache فقط؟
لا. على الرغم من الاسم، يرسل ab طلبات HTTP و HTTPS عادية إلى أي خادم. إنه يعمل مع Nginx، Node، Go، Python، أو أي مضيف يتحدث HTTP. ارتباطه بـ Apache هو فقط أن الأداة تأتي مع خادم Apache HTTP Server.
ما هو مستوى التزامن وعدد الطلبات التي يجب أن أستخدمها؟
ابدأ بقيمة منخفضة ثم زدها. جرب -n 1000 -c 10، ثم ارفع -c إلى 25، 50، 100، وراقب أين تتوقف الطلبات في الثانية عن الارتفاع وتبدأ الطلبات الفاشلة في الظهور. نقطة التحول هذه هي تقريبًا المكان الذي تصل فيه نقطة النهاية إلى أقصى طاقتها. طابق أقصى تزامن لديك مع حركة المرور الحقيقية المتوقعة بدلاً من اختيار رقم كبير.
لماذا تكون طلباتي الفاشلة مرتفعة بينما تعمل واجهة برمجة التطبيقات (API) بشكل جيد؟
يصنف ab الطلب على أنه فاشل إذا اختلف طول الاستجابة بين الطلبات، وهو أمر طبيعي لـ JSON الديناميكي. أضف العلامة -l لإيقاف احتساب اختلافات الطول كأخطاء. ثم تحقق من سطر الاستجابات غير 2xx لترى ما إذا كانت هناك أخطاء حقيقية.
هل يمكن لـ ab اختبار نقطة نهاية تحتاج إلى رمز تسجيل دخول (login token)؟
نعم، إذا كان لديك بالفعل رمز مميز. مرره باستخدام -H "Authorization: Bearer YOUR_TOKEN". ما لا يستطيع ab فعله هو تسجيل الدخول أولاً للحصول على رمز مميز جديد، ثم استخدامه. هذا تدفق متعدد الخطوات، وتحتاج إلى أداة قائمة على السيناريوهات مثل Apidog لذلك.
هل يدعم ab بروتوكول HTTP/2؟
لا. يتحدث ab بروتوكول HTTP/1.x، ووفقًا للوثائق الرسمية، فإنه لا ينفذ ذلك بالكامل. إذا كان سلوك الخادم الخاص بك تحت HTTP/2 مهمًا، فاستخدم أداة تحميل تدعم HTTP/2 بدلاً من ذلك.
