مشروع: اختبار تحميل خدمة
مشروع: اختبار تحميل خدمة
أعطتك الدروس التسعة السابقة المفردات والأدوات والتقنيات. هذا الدرس يُغلق الدائرة: ستخطط وتكتب السكريبت وتُنفّذ وتُقدّم تقريرًا عن اختبار تحميل كامل لواجهة HTTP واقعية. كل خطوة تعكس بدقة كيف يُجري مهندسو Google SRE ومهندسو الأداء في Netflix مراجعات الجاهزية للإنتاج — بدءًا من كتابة خطة اختبار يوافق عليها أصحاب المصلحة، وصولًا إلى فتح تذكرة Jira بسبب جذر التراجع في الأداء.
الخطوة الأولى — اكتب خطة الاختبار قبل لمس الطرفية
اختبار التحميل بدون خطة هو تجربة بدون فرضية. تجيب خطة الاختبار على خمسة أسئلة قبل إرسال أي حزمة:
- الخدمة قيد الاختبار (SUT): أي نقاط نهاية، وأي بيئة (staging أو مرآة الإنتاج)، وأي مجموعة بيانات؟
- معايير النجاح (SLOs): كيف يبدو "النجاح"؟ عبّر عنه بأهداف P99 للكمون ومعدل الخطأ والإنتاجية — لا بصفات مبهمة.
- ملف التحميل: طلبات في الثانية في الحالة الثابتة، مدة الرفع، مدة النقع، شكل الارتفاع المفاجئ. استند إلى percentiles حركة الإنتاج من Grafana/Datadog لتكون الأرقام مستندة للواقع.
- نطاق المراقبة: أي لوحات تحكم وسجلات وعيّنات من أداة الاستبيان ستكون نشطة خلال التشغيل؟
- حدود التراجع وتأثير الاختبار: إذا تدهورت الخدمة إلى أقل من 20 % من طاقتها، من يقرر الإيقاف؟ ما قواطع الدوائر أو رؤوس تحديد المعدل التي تمنع الحادث العرضي على التبعيات المشتركة؟
الخطوة الثانية — تحضير البيئة
استخدم بيئة staging تطابق الإنتاج بمقياس واقعي: نفس أنواع الأجهزة، نفس حجم قاعدة البيانات (أو نسخة إنتاجية معقّمة)، بنفس قواعد CDN معطّلة، ونفس feature flags. اختبار على مجموعة staging منخفضة التوفير لا يخبرك بشيء مفيد عن سعة الإنتاج.
أنشئ منفّذ k6 على جهاز (أو k6 Cloud / مشغّل k6 OSS الموزّع من Grafana) ليس على المضيف ذاته للخدمة قيد الاختبار. يجب أن يكون RTT الشبكة بين مُولّد الحمل والخدمة واقعيًا — نفس منطقة AWS، نفس VPC، مماثل لجغرافيا العميل الحقيقي. صدّر مقاييس البداية من Prometheus/Datadog إلى لقطة حتى تتمكن من مقارنة القبل والبعد.
الخطوة الثالثة — كتابة سكريبت k6
يجب أن يُنمذج سكريبتك رحلات المستخدم الحقيقية، لا ضرب نقاط نهاية عشوائية. بالنسبة لـ API سلة التسوق، الرحلات المحورية هي: تصفّح الكتالوج، عرض تفاصيل المنتج، إضافة إلى السلة، إتمام الشراء. رجّحها حسب بيانات التحليلات — في معظم الشركات حجم التصفّح أكبر 10 مرات من حجم الشراء.
استخدم k6 scenarios لترميز أشكال تنفيذ متعددة في ملف واحد، حتى يشترك اختبار CI، واختبار النقع، واختبار الارتفاع في نفس السكريبت دون تكرار.
الخطوة الرابعة — التشغيل مع تفعيل المراقبة الكاملة
لا تُشغّل اختبار تحميل في الظلام أبدًا. قبل التنفيذ، تأكد أن فترات scrape في Prometheus عند 15 ثانية أو أقل، وأن التتبع الموزع يأخذ عينات بنسبة 100 % (أو 10 % على الأقل مع tail-based sampling على التتبعات البطيئة)، وأن محلل الأداء (pprof, async-profiler, py-spy) جاهز للتشغيل عند الطلب.
أثناء تشغيل الاختبار، راقب أربع إشارات في آنٍ واحد: CPU وذاكرة الخدمة (هل نحن مقيّدون بالمعالج أم بالذاكرة؟)، استخدام مجمع اتصالات قاعدة البيانات (استنزاف المجمع هو السبب الأول لتدهور الكمون المفاجئ عند 500+ RPS)، اتجاه كمون P99 (هل مستقر أم يرتفع تدريجيًا؟)، وتكرار توقفات GC لخدمات JVM/Go.
الخطوة الخامسة — تحليل النتائج: من الأرقام إلى الجذر
المخرجات الخام من k6 أو InfluxDB هي بيانات، ليست رؤية. مهمتك الانتقال من "ارتفع P99 إلى 1.2 ثانية عند 180 VU" إلى "استنزاف مجمع الاتصالات على النسخة القرائية عند ~175 استعلامًا متزامنًا." هذه السلسلة من الاستدلال تتطلب ربط ثلاث طبقات:
- جانب العميل (k6): متى بالضبط تدهور الكمون؟ ما RPS وعدد VU المرتبطان؟ هل قفز معدل الخطأ في نفس الوقت أم تأخر عن تسلق الكمون؟
- جانب الخدمة (APM / traces): أي span استحوذ على الكمون المضاف — كود التطبيق أم استعلام قاعدة البيانات أم الشبكة؟ استخدم Jaeger أو Tempo للعثور على أبطأ التتبعات خلال نافذة التدهور.
- البنية التحتية (Prometheus): هل وُصل لأي حد من حدود الموارد؟ الإشارات الكلاسيكية: تقييد CPU (
container_cpu_cfs_throttled_seconds_total)، أحداث OOM، وقت انتظار مجمع اتصالات قاعدة البيانات (pgbouncer_client_wait_seconds)، توقفات GC (jvm_gc_pause_seconds).
الخطوة السادسة — كتابة تقرير الأداء
تقرير الأداء هو عقد بين الهندسة والأعمال. يجب أن يحتوي على: (1) ملخص تنفيذي بفقرة واحدة بحكم نجاح/فشل واضح مقابل كل SLO؛ (2) مخطط سلاسل زمنية يُظهر كمون P50/P95/P99 ومعدل RPS على مدار الاختبار؛ (3) الاختناقات المُحدّدة مرتّبة حسب الأثر؛ (4) توصيات محددة وقابلة للتنفيذ (لا "حسّن استعلامات قاعدة البيانات" — بل "أضف مؤشرًا مركّبًا على (user_id, created_at DESC) في جدول orders، الانخفاض المُقدّر لوقت الاستعلام من 180 مللي ثانية إلى 12 مللي ثانية بناءً على EXPLAIN ANALYZE")؛ و(5) قسم مخاطر التراجع يُوضّح أي التغييرات آمنة للشحن وأيها يحتاج إعادة اختبار.
في شركات مثل LinkedIn وStripe، تصبح تقارير الأداء وثائق حية تُتبّع في نفس نظام إدارة المشاريع مثل تذاكر الهندسة. التراجع المكتشف في CI يُشير إلى تقرير الخط الأساسي الأصلي، مما يجعل الفارق لا يُنكر والإصلاح محسوبًا على PR محدد.
--out json في k6 مع سكريبت Python أو Go قصير يستطيع إنتاج تقرير Markdown، وحفظه كمنتج CI، ونشر ملخص Slack بحالة النجاح/الفشل في أقل من 30 ثانية. هكذا تجعل الأداء بوابة من الدرجة الأولى لا طقسًا دوريًا.
تجميع الكل: قائمة التحقق الجاهزة للإنتاج
- مراجعة خطة الاختبار من قِبَل الباك-إند ومدير قاعدة البيانات والمهندس المناوب قبل التنفيذ
- البيانات مُعبّأة مسبقًا؛ لا توليد بيانات داخل حلقة k6 VU
- بيئة staging مُتحقق منها لتطابق أنواع أجهزة الإنتاج وعدد النسخ
- المراقبة نشطة: Prometheus والتتبع والمحلل كلها تعمل
- العتبات تُرمّز SLOs، لا فقط percentiles الكمون — أدرج معدل الخطأ
- سيناريوهات الارتفاع والنقع تُشغَّل بالإضافة إلى الحالة الثابتة
- السبب الجذري مُؤكّد على طبقة البنية التحتية قبل الإعلان عن اختناق
- التقرير يتضمن تذاكر قابلة للتنفيذ، لا نصائح عامة
- بوابة تكامل CI تُشغّل سيناريو الحالة الثابتة على كل PR على المسار الحرج
هذا الانضباط الشامل هو ما يُفرّق بين مهندس الأداء الذي يشحن الثقة ومن يشحن الشك. كل درس في هذه الدورة — من قانون Little إلى استبيان flamegraphs وحدة المعالج — يُغذّي هذه العملية الواحدة. المخرج ليس رقمًا؛ إنه قرار هندسي موقّع بشأن ما إذا كانت الخدمة جاهزة لحمل إنتاجي حقيقي.