Artillery هي مجموعة أدوات مفتوحة المصدر لاختبار التحميل مبنية على Node.js. تتيح لك توليد حركة مرور عالية التزامن على واجهة برمجة التطبيقات (API) من خلال ملف YAML بسيط: تحدد مراحل التحميل، تصف تدفقات الطلبات، تشغل artillery run script.yml، ثم تقرأ نسب زمن الاستجابة المئوية، معدلات الطلبات، وعدد الأخطاء. يشرح هذا الدليل طريقة تثبيت Artillery v2، كتابة اختبار عملي، تشغيله، استخراج النتائج بالطريقة الصحيحة في v2، وربطه بمسار CI.
ما هو Artillery ومتى تستخدمه؟
ينشئ Artillery مستخدمين افتراضيين (VUs) يرسلون طلبات إلى نقاط النهاية لديك ويقيسون قدرة النظام على تحمل الحمل المستمر. المستخدم الافتراضي هو عميل مُحاكى ينفذ سيناريو خطوة بخطوة، كما يفعل مستخدم أو خدمة حقيقية.
استخدم Artillery عندما تريد إجابات عملية على أسئلة الأداء مثل:
- كيف يتغير زمن الاستجابة p95 عند 50 طلبًا في الثانية؟
- عند أي معدل وصول تبدأ الأخطاء بالظهور؟
- هل تبقى واجهة API مستقرة لمدة 5 دقائق من الحمل المستمر؟
- هل يتدهور الأداء تدريجيًا مع استمرار الضغط؟
الميزة الأساسية في Artillery أن الاختبار تصريحي. بدل كتابة حلقات تزامن يدويًا، تصف شكل الحمل في YAML. وبما أنه يعمل فوق Node.js، يمكنك تشغيل نفس الاختبار محليًا وفي CI.
إذا كنت تقارن الأدوات، راجع ملخص أفضل أدوات اختبار التحميل ومقارنة برامج اختبار التحميل لفهم الفروقات بين k6 وJMeter وGatling وغيرها.
تثبيت Artillery v2
اسم الحزمة هو artillery، والإصدار الرئيسي الحالي هو v2. ثبته عالميًا عبر npm:
npm install -g artillery@latest
artillery version
تحتاج إلى إصدار LTS حديث من Node.js. يعمل Artillery على Windows وmacOS وLinux.
إذا كنت لا تريد تثبيت الحزمة عالميًا، استخدم npx:
npx artillery@latest run script.yml
كتابة اختبار Artillery
يتكون ملف الاختبار من قسمين أساسيين:
-
config: يحدد الهدف ومراحل الحمل والمتغيرات. -
scenarios: يحدد ما يفعله كل مستخدم افتراضي.
مثال كامل:
config:
target: "https://api.example.com"
phases:
- name: "Warm up"
duration: 60
arrivalRate: 5
- name: "Ramp to peak"
duration: 120
arrivalRate: 5
rampTo: 50
- name: "Sustained load"
duration: 300
arrivalRate: 50
maxVusers: 500
variables:
productId:
- "1001"
- "1002"
scenarios:
- name: "Browse and create order"
flow:
- get:
url: "/v1/products/{{ productId }}"
- post:
url: "/v1/orders"
json:
productId: "{{ productId }}"
quantity: 2
فهم قسم config
config.target هو المضيف الأساسي الذي تُرسل إليه الطلبات. أي url داخل السيناريو يُضاف إلى هذا الأساس.
مثال:
target: "https://api.example.com"
مع:
url: "/v1/products/1001"
ينتج عنه الطلب:
https://api.example.com/v1/products/1001
أهم مفاتيح phases
config.phases هي مصفوفة مراحل تُنفذ بالترتيب:
phases:
- duration: 60
arrivalRate: 5
- duration: 120
arrivalRate: 5
rampTo: 50
المفاتيح الأكثر استخدامًا:
-
duration: مدة المرحلة بالثواني أو كسلسلة مثل"5m". -
arrivalRate: عدد المستخدمين الافتراضيين الجدد في كل ثانية. -
rampTo: رفع معدل الوصول تدريجيًا حتى هذه القيمة. -
arrivalCount: عدد ثابت من المستخدمين الافتراضيين موزع على المرحلة. -
maxVusers: الحد الأعلى للمستخدمين الافتراضيين المتزامنين. -
name: اسم المرحلة في الإخراج.
انتبه إلى نقطة مهمة: duration يحدد مدة إنشاء مستخدمين افتراضيين جدد، وليس دائمًا مدة الاختبار بالكامل. إذا بدأ مستخدم افتراضي قرب نهاية المرحلة واستغرق سيناريوه وقتًا أطول، يستمر التشغيل حتى ينهي هذا المستخدم خطواته.
فهم قسم scenarios
scenarios هي قائمة بالسيناريوهات. كل سيناريو يحتوي على flow، وهي خطوات HTTP ينفذها المستخدم الافتراضي بالترتيب.
مثال:
scenarios:
- name: "Login and fetch profile"
flow:
- post:
url: "/login"
json:
email: "user@example.com"
password: "secret"
- get:
url: "/profile"
أفعال HTTP المدعومة تشمل:
getpostputpatchdelete
لإرسال جسم JSON:
- post:
url: "/v1/orders"
json:
productId: "{{ productId }}"
quantity: 2
وتُستخدم صيغة {{ variableName }} لقراءة المتغيرات.
يمكنك أيضًا استخدام weight لتحديد احتمالية اختيار سيناريو معين:
scenarios:
- name: "Browse"
weight: 80
flow:
- get:
url: "/products"
- name: "Create order"
weight: 20
flow:
- post:
url: "/orders"
json:
productId: "1001"
تمرير بيانات الاختبار من CSV
القيم الثابتة مناسبة لاختبار دخان بسيط، لكنها لا تكفي لمحاكاة استخدام واقعي. لاستخدام بيانات متعددة، استخدم config.payload.
ملف users.csv مثلًا:
email,password
user1@example.com,password1
user2@example.com,password2
ملف Artillery:
config:
target: "https://api.example.com"
payload:
path: "./users.csv"
fields:
- "email"
- "password"
phases:
- duration: 120
arrivalRate: 20
scenarios:
- name: "Login"
flow:
- post:
url: "/login"
json:
email: "{{ email }}"
password: "{{ password }}"
كل مستخدم افتراضي يقرأ صفًا، وتصبح أسماء الأعمدة متغيرات يمكن استخدامها داخل السيناريو.
تشغيل الاختبار
الأمر الأساسي:
artillery run script.yml
لتجاوز الهدف دون تعديل الملف:
artillery run --target https://staging.example.com script.yml
أو بالاختصار:
artillery run -t https://staging.example.com script.yml
لتمرير متغيرات من سطر الأوامر:
artillery run -v '{ "productId": ["1001","1002"] }' script.yml
علامات مفيدة:
-
--targetأو-t: تجاوزconfig.target. -
--environmentأو-e: اختيار بيئة منconfig.environments. -
--configأو-c: تحميل إعدادات من ملف منفصل. -
--insecureأو-k: تجاهل تحقق TLS في بيئات الاختبار ذات الشهادات الموقعة ذاتيًا.
مثال لاستخدام البيئات:
config:
target: "https://api.example.com"
environments:
staging:
target: "https://staging.example.com"
production:
target: "https://api.example.com"
phases:
- duration: 60
arrivalRate: 10
scenarios:
- flow:
- get:
url: "/health"
تشغيل بيئة staging:
artillery run -e staging script.yml
قراءة النتائج
أثناء التشغيل، يطبع Artillery مقاييس مجمعة كل 10 ثوانٍ تقريبًا. في النهاية، يظهر ملخص يتضمن أهم المؤشرات.
ركز على:
- معدل الطلبات: عدد الطلبات في الثانية التي حققها الاختبار فعليًا.
- النسب المئوية للكمون: مثل p50 وp95 وp99.
- الأخطاء: الطلبات الفاشلة، مهلات الانتظار، والاستجابات غير الناجحة.
- عدد المستخدمين الافتراضيين: لمعرفة ما إذا كان الاختبار وصل إلى الحمل المطلوب.
لا تعتمد على المتوسط فقط. قد يكون متوسط زمن الاستجابة جيدًا بينما يتضخم p99 إلى عدة ثوانٍ. عادةً، p95 وp99 يكشفان مشاكل الأداء قبل أن تظهر بوضوح في المتوسط.
إذا ظهرت الأخطاء فقط أثناء مرحلة الحمل المستمر، فقد تكون وصلت إلى نقطة تشبع تحتاج إلى تحليل. لمزيد من التفاصيل حول المقاييس المهمة، راجع دليل اختبار أداء API.
إنشاء تقرير في Artillery v2
تغيرت آلية التقارير في Artillery عبر الإصدارات، وهذه نقطة تسبب لبسًا شائعًا.
في الإصدارات القديمة، كانت بعض الشروحات تستخدم:
artillery run --output report.json script.yml
artillery report report.json
الجزء الأول ما زال يعمل. أما artillery report فلم يعد يعمل في Artillery v2 الحالي.
لإنشاء ملف نتائج JSON:
artillery run --output report.json script.yml
هذا ينتج ملفًا قابلًا للقراءة آليًا يمكن استخدامه في CI أو تحليله بأدوات مثل jq.
مثال لاستخراج p95:
jq '.aggregate.summaries["http.response_time"].p95' report.json
لديك 3 خيارات عملية بدل تقرير HTML القديم:
1. تحليل JSON بنفسك
مناسب لمسارات CI، حيث تريد فشل المهمة إذا تجاوز الأداء حدًا معينًا.
مثال:
P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
echo "p95 = $P95 ms"
if (( $(echo "$P95 > 500" | bc -l) )); then
echo "p95 exceeded budget"
exit 1
fi
2. استخدام Artillery Cloud
إذا كنت تريد لوحة تحكم مستضافة:
artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
3. إرسال المقاييس إلى نظام المراقبة
يمكنك دفع المقاييس إلى مكدس المراقبة لديك باستخدام publish-metrics أو OpenTelemetry، بحيث تظهر أزمنة الاستجابة ومعدلات الأخطاء في نفس لوحات الإنتاج.
تشغيل Artillery في CI
بما أن Artillery عبارة عن CLI مبني على Node.js، يمكن تشغيله بسهولة داخل GitHub Actions أو أي نظام CI.
مثال GitHub Actions:
name: Load test
on: [workflow_dispatch]
jobs:
artillery:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
- run: npm install -g artillery@latest
- run: artillery run --output report.json script.yml
- uses: actions/upload-artifact@v4
with:
name: artillery-report
path: report.json
هذا المثال يعمل يدويًا عبر workflow_dispatch. من الأفضل عادةً تشغيل اختبارات التحميل الثقيلة يدويًا أو بجدول زمني، وليس مع كل commit، لأنها تستهلك وقتًا ونطاقًا تردديًا حقيقيًا.
لإضافة حد أداء يفشل المهمة عند تجاوزه:
- name: Check p95 latency
run: |
P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
echo "p95 = $P95 ms"
if (( $(echo "$P95 > 500" | bc -l) )); then
echo "p95 exceeded 500ms"
exit 1
fi
أين تتلاءم Apidog: الاختبار الوظيفي وحماية CI
تجيب Artillery على سؤال:
هل يمكن لواجهة API تحمل هذا القدر من حركة المرور؟
وهذا هو اختبار التحميل والأداء.
لكن هناك سؤالًا آخر لا يقل أهمية:
هل ما زالت واجهة API تُرجع الاستجابات الصحيحة بعد تغيير الكود؟
هذا هو الاختبار الوظيفي واختبار الانحدار، وهنا يأتي دور Apidog.
Apidog هي منصة API شاملة للتصميم، التصحيح، المحاكاة، التوثيق، والاختبار الآلي. يمكن استخدام سيناريوهات الاختبار لتجميع نقاط النهاية في خطوات منطقية، والتحقق من أكواد الحالة، أجسام الاستجابة، والعقود.
كن واضحًا بشأن الحدود: تتضمن Apidog ميزة اختبار أداء، لكنها محدودة بحد أقصى 100 مستخدم افتراضي. هذا مفيد لاكتشاف الانحدارات الواضحة، لكنه ليس بديلًا عن Artillery عندما تحتاج إلى تزامن عالٍ أو حمل موزع واسع. للمزيد، راجع اختبار تحميل واجهات برمجة التطبيقات بدون Python واختبار أداء API في Apidog.
الاستخدام العملي:
- استخدم Artillery لاختبار قابلية التوسع تحت الحمل.
- استخدم Apidog CLI لاختبارات وظيفية وانحدارية داخل CI.
تثبيت Apidog CLI:
npm install -g apidog-cli
تشغيل سيناريو اختبار في CI:
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t <TEST_SCENARIO_ID> \
-e <ENVIRONMENT_ID> \
-r cli,junit \
--out-dir ./apidog-reports
شرح العلامات:
-
--access-token: رمز الوصول إلى Apidog. -
-t: معرف سيناريو الاختبار. -
-e: معرف البيئة. -
-r cli,junit: إخراج للكونسول وتقرير JUnit XML. -
--out-dir: مجلد حفظ التقارير.
لشرح تفصيلي، راجع البرنامج التعليمي لواجهة سطر أوامر Apidog، ولتصميم مسارات CI/CD، راجع أفضل الممارسات لـ CI/CD لاختبار API.
إذا كنت تريد حماية CI باختبارات وظيفية وتعاقدية بجانب اختبارات تحميل Artillery، يمكنك استخدام Apidog لبناء سيناريوهات تحقق قابلة للتشغيل تلقائيًا.
الأسئلة الشائعة
ما هو اختبار التحميل باستخدام Artillery؟
اختبار التحميل باستخدام Artillery هو استخدام أداة Artillery مفتوحة المصدر لمحاكاة عدد كبير من المستخدمين الافتراضيين الذين يرسلون طلبات إلى واجهة API. تصف الحمل وتدفق الطلبات في ملف YAML، ثم تقيس زمن الاستجابة، معدلات الطلبات، والأخطاء لمعرفة سلوك النظام تحت الضغط.
هل Artillery مجانية ومفتوحة المصدر؟
نعم. واجهة سطر أوامر Artillery الأساسية مجانية ومفتوحة المصدر، وتتوفر عبر npm باسم artillery. توجد أيضًا خدمة مدفوعة مستضافة باسم Artillery Cloud لتوفير لوحات نتائج، لكن يمكنك تشغيل اختبارات تحميل كاملة محليًا وفي CI بدونها.
كيف تشغل اختبار تحميل باستخدام Artillery؟
ثبّت Artillery:
npm install -g artillery@latest
اكتب ملف YAML يحتوي على config وscenarios، ثم شغله:
artillery run script.yml
سيطبع Artillery مقاييس مباشرة أثناء التشغيل وملخصًا عند الانتهاء.
كيف تُنشئ تقرير Artillery؟
استخدم:
artillery run --output report.json script.yml
هذا ينتج ملف JSON قابلًا للتحليل. أمر artillery report القديم الذي كان ينتج HTML تمت إزالته من Artillery CLI. بدلًا من ذلك، حلل JSON باستخدام jq، أو استخدم Artillery Cloud، أو ادفع المقاييس إلى نظام المراقبة لديك.
Artillery مقابل k6 أو JMeter: أيهم تختار؟
كل الأدوات الثلاثة مناسبة لاختبارات تحميل واسعة، لكن نموذج الاستخدام مختلف:
- Artillery يستخدم YAML وNode.js، وهو مناسب للفرق القريبة من منظومة JavaScript.
- k6 يستخدم JavaScript بنموذج code-first.
- JMeter يعتمد على واجهة رسومية ويستند إلى Java وله تاريخ طويل من الإضافات.
للمقارنة الأعمق، راجع مقارنة Gatling vs JMeter. اختر الأداة التي تناسب طريقة عمل فريقك، ثم أضف اختبارات وظيفية في CI لتغطية السلوك الصحيح بجانب الأداء.
Top comments (0)