هناك العديد من الطرق لاختبار واجهات برمجة التطبيقات والواجهات. فيما يتعلق بفتح الوصول على نطاق واسع إلى Acronis Cyber Platform ، فقد اضطررنا إلى البحث عن طرق لاختبار الخدمات "للمتانة" من مجموعة متنوعة من المناصب. في هذا المنشور ، يتحدث مهندس البرمجيات الرائد في Acronis ، ديمتري سالوماتين ، عن الطريقة التي اخترنا بها إطار الاختبار ، والصعوبات التي واجهناها ، والتحسينات التي يتعين علينا القيام بها بأنفسنا.

يجب أن أقول على الفور أننا في Acronis حريصون بشكل خاص على اختبار واجهات برمجة التطبيقات. الحقيقة هي أن منتجاتنا تصل إلى الخدمات من خلال نفس واجهات برمجة التطبيقات التي يتم استخدامها لتوصيل الأنظمة الخارجية. لذلك ، مطلوب اختبار أداء كل واجهة. نقوم باختبار تشغيل واجهة برمجة التطبيقات وعزل تشغيل واجهة المستخدم بمعزل عن غيرها. ستتيح لك نتائج الاختبار تقييم ما إذا كانت واجهة برمجة التطبيقات (API) نفسها تعمل بشكل جيد ، وكذلك واجهات المستخدم. تأكيد التطوير الناجح أو صياغة مهمة لمزيد من التطوير.
لكن الاختبارات تختلف. في بعض الأحيان لا تظهر الخدمة تدهورًا على الفور. حتى إذا قمنا بتشغيل خدمة مشابهة للمنتجات التي تم إصدارها بالفعل في الإصدار ، للتحقق ، يمكنك تحميلها بنفس البيانات المستخدمة "في المنتجات". في هذه الحالة ، يمكنك رؤية الانحدار ، لكن من المستحيل تمامًا تقييم المنظور. أنت ببساطة لا تعرف ما الذي سيحدث إذا زاد حجم البيانات بشكل حاد أو زاد عدد الطلبات.
فيما يلي رسم بياني يوضح كيف يتغير عدد واجهات برمجة التطبيقات التي تتم معالجتها بواسطة الواجهة الخلفية في الثانية الواحدة مع نمو البيانات في النظام

افترض أن الخدمة التي نختبرها في حالة نموذجية لبداية هذا الجدول. في هذه الحالة ، حتى مع نمو بسيط للنظام ، ستنخفض سرعة واجهة برمجة التطبيقات هذه بشكل حاد.
لاستبعاد مثل هذه المواقف ، نزيد من كمية البيانات عدة مرات ، ونزيد من عدد مؤشرات الترابط المتوازية لفهم كيفية تصرف الخدمة إذا زاد الحمل بشكل كبير.
ولكن هناك فارق بسيط آخر. إذا تغير عمل خدمة "مألوفة" وفقًا للزيادة في كمية البيانات ، وتطويرها ، وظهور وظائف جديدة ، مع خدمات جديدة ، يصبح الموقف أكثر تعقيدًا. عندما تظهر خدمة جديدة من الناحية النظرية في منتج ما ، يجب أخذها في الاعتبار من عدة زوايا مختلفة. في هذا الموقف ، تحتاج إلى إعداد مجموعات بيانات خاصة ، وإجراء اختبار الحمل ، واقتراح حالات الاستخدام الممكنة.
ميزات اختبار الأداء في أكرونيس
عادة ، تجري عمليات الاختبار الخاصة بنا في "نمط حلزوني". تتضمن إحدى مراحل الاختبار استخدام واجهة برمجة التطبيقات (API) لزيادة عدد الكيانات (تغيير الحجم) ، والثانية التي تؤدي عمليات جديدة على مجموعات البيانات الموجودة (الاستخدام). جميع الاختبارات تعمل في عدد مختلف من المواضيع. على سبيل المثال ، لدينا خدمة الحيوانات ، ولها واجهات برمجة التطبيقات التالية:
POST /animals PUT /animals/<id> GET /animals?filter=criteria
1 و 2 عبارة عن واجهات برمجة التطبيقات تسمى اختبارات التحجيم - وهي تزيد من عدد الكيانات الجديدة في النظام.
3 هي واجهات برمجة التطبيقات تسمى في مرحلة الاستخدام. يحتوي واجهة برمجة التطبيقات هذه على الكثير من خيارات التصفية. وفقا لذلك ، سيكون هناك أكثر من اختبار
وبالتالي ، من خلال إجراء اختبارات التحجيم والاستخدام بشكل متكرر ، نحصل على صورة للتغيير في أداء النظام مع نموه




الإطار المطلوب ...
من أجل إجراء اختبارات واسعة النطاق لعدد كبير من الخدمات الجديدة والمحدثة ، كنا بحاجة إلى إطار عمل مرن يتيح لنا تشغيل برامج نصية مختلفة. والشيء الرئيسي هو اختبار واجهة برمجة التطبيقات (API) حقًا ، وليس فقط إنشاء عبء على الخدمات من خلال عمليات متكررة.
يمكن أن يحدث اختبار الأداء على كل من الحمل الاصطناعي واستخدام نمط التحميل المسجل من الإنتاج. كلا النهجين لهما إيجابيات وسلبيات. يمكن وصف الطريقة التي بها حمل حقيقي باختبار الإجهاد - نحصل على صورة حقيقية لأداء النظام في ظل هذا الحمل ، لكن ليس لدينا القدرة على تحديد مناطق المشكلات بسهولة ، وقياس إنتاجية المكونات بشكل فردي ، ولا نحصل على الأرقام الدقيقة التي يمكن أن تحمل المكونات الفردية. في حالة النهج الاصطناعي ، نحصل على أرقام دقيقة ، ولدينا مرونة كبيرة ، ويمكننا بسهولة إصلاح المناطق التي تعاني من مشاكل ، ومن خلال تشغيل العديد من البرامج النصية للاختبار على التوازي ، يمكننا إعادة إنتاج عبء الإجهاد. العيوب الرئيسية للنهج الثاني هي ارتفاع تكاليف العمالة لكتابة البرامج النصية للاختبار ، وكذلك تزايد خطر فقدان بعض النصوص المهمة. لذلك ، قررنا الذهاب بطريقة أكثر صعوبة.
لذلك ، تم تحديد اختيار إطار من المهمة. ومهمتنا هي:
- العثور على اختناقات API
- تحقق مقاومة الأحمال العالية
- تقييم فعالية الخدمة مع نمو وحدات تخزين البيانات
- تحديد الأخطاء التراكمية التي تحدث مع مرور الوقت
هناك الكثير من أطر الأداء في السوق والتي يمكنها إطلاق عدد كبير من الطلبات المماثلة. كثير منهم لا يسمح بتغيير أي شيء في الداخل (على سبيل المثال ، Apache Benchmark) أو مع قدرات محدودة لوصف البرامج النصية (على سبيل المثال ، JMeter).
نستخدم عادةً نصوصًا أكثر تعقيدًا في الاختبار. في كثير من الأحيان ، يجب إجراء مكالمات API بالتسلسل - واحدة تلو الأخرى ، أو لتغيير معلمات الطلب وفقًا لنوع من المنطق. أبسط مثال عندما نريد اختبار واجهة برمجة تطبيقات REST للنموذج
PUT /endpoint/resource/<id>
في هذه الحالة ، يجب أن تعرف مقدمًا <id> المورد الذي نريد تغييره لقياس وقت تنفيذ استعلام net.
لذلك ، نحتاج إلى القدرة على إنشاء برامج نصية لتشغيل استعلامات اختبار معقدة.
أسرع
نظرًا لأن منتجات Acronis مصممة للتحميل العالي ، فإننا نختبر واجهات برمجة التطبيقات في عشرات الآلاف من الطلبات في الثانية. اتضح أنه ليس كل إطار يمكن أن يسمح بذلك. على سبيل المثال ، ليس بيثون دائمًا ولا يمكن استخدامه دائمًا للاختبار ، نظرًا لخصائص اللغة ، تكون القدرة على إنشاء حمل كبير متعدد الخيوط محدودة
مشكلة أخرى هي استخدام الموارد. على سبيل المثال ، نظرنا أولاً إلى إطار عمل الجراد ، والذي يمكن تشغيله من عقد متعددة للأجهزة في وقت واحد والحصول على أداء جيد. ولكن في الوقت نفسه ، يتم إنفاق الكثير من الموارد على عمل نظام الاختبار ، وهو مكلف للعمل.
نتيجةً لذلك ، اخترنا إطار عمل K6 ، والذي يسمح لنا بوصف النصوص في Javascript الكاملة ، ويوفر أداء أعلى من المتوسط. هذا الإطار مكتوب في Go ، ويكتسب شعبية بسرعة. على سبيل المثال ، على جيثب ، تلقى المشروع بالفعل ما يقرب من 5.5 ألف نجم! تتطور K6 بشكل نشط ، وقد اقترح المجتمع بالفعل ما يقرب من 3 آلاف عملية تنفيذ ، ويضم المشروع 50 مساهمًا أنشأوا 36 فرعًا من الكودات. بالطبع ، لا يزال K6 بعيدًا عن المثالية ، ولكن تدريجياً يتحسن الإطار ، ويمكنك أن تقرأ عن المقارنة مع Jmeter
هنا .
الصعوبات وحلولها
بالنظر إلى "شباب" K6 ، حتى بعد اختيار متوازن للإطار ، واجهنا عددًا من المشكلات. على سبيل المثال ، قبل اختبار API مثل / endpoint / ، يجب أولاً العثور على نقاط النهاية هذه بطريقة أو بأخرى. لا يمكننا استخدام نفس القيم ، لأن التخزين المؤقت للنتائج سيكون غير صحيح.
يمكنك الحصول على البيانات التي تحتاجها بطرق مختلفة:
- يمكنك طلبها عبر API
- يمكنك استخدام الوصول المباشر إلى قاعدة البيانات
الطريقة الثانية تعمل بشكل أسرع ، وعند استخدام قواعد البيانات العلائقية ، غالبًا ما يكون ذلك أكثر ملاءمة ، لأنه يتيح لك توفير وقت كبير أثناء الاختبارات المطولة. "لكن" فقط هو أنه يمكنك استخدامه فقط إذا تم كتابة رمز الخدمة والاختبارات من قبل نفس الأشخاص. نظرًا للعمل من خلال قاعدة البيانات ، يجب أن تكون الاختبارات محدثة دائمًا. ومع ذلك ، في حالة K6 ، لا يحتوي الإطار على آليات الوصول إلى قواعد البيانات. لذلك ، كان علي أن أكتب الوحدة المناسبة بنفسي.
تنشأ مشكلة أخرى عند اختبار واجهات برمجة التطبيقات غير العاطفية. في هذه الحالة ، من المهم أن يتم استدعاءهم مرة واحدة فقط باستخدام نفس المعلمات (على سبيل المثال ، واجهة برمجة تطبيقات DELETE). في اختباراتنا ، نقوم بإعداد بيانات الاختبار مسبقًا ، في مرحلة الإعداد ، عند إعداد النظام وإعداده. وأثناء الاختبار ، يتم إجراء قياسات لمكالمات واجهة برمجة التطبيقات (API) الخالصة ، لأن الوقت والموارد اللازمة لإعداد البيانات لم تعد مطلوبة. ومع ذلك ، فإن هذا يثير مشكلة توزيع البيانات المعدة مسبقًا عبر التدفقات غير المتزامنة للاختبار الرئيسي. تم حل هذه المشكلة بنجاح عن طريق كتابة قائمة انتظار بيانات داخلية. لكن هذا موضوع كبير ، سنناقشه في المشاركات القادمة.
إطار جاهز
خلاصة القول ، أود أن أشير إلى أنه لم يكن من السهل العثور على إطار جاهز تمامًا ، ولا يزال يتعين علي إنهاء بعض الأشياء بيدي. ومع ذلك ، لدينا اليوم أداة مناسبة لنا ، والتي ، مع مراعاة التحسينات ، تتيح لنا إجراء اختبارات معقدة ، وإنشاء محاكاة للأحمال الكبيرة لضمان أداء واجهة برمجة التطبيقات (API) وواجهة المستخدم الرسومية (GUI) في ظروف مختلفة.
في المنشور التالي ، سأتحدث عن كيفية حل مشكلة اختبار الخدمة التي تدعم الاتصال المتزامن لمئات الآلاف من الاتصالات باستخدام الحد الأدنى من الموارد.