التكامل المستمر في Yandex

يمثل الحفاظ على قاعدة رموز ضخمة مع ضمان إنتاجية عالية لعدد كبير من المطورين تحديًا خطيرًا. على مدى السنوات الخمس الماضية ، طورت ياندكس نظامًا خاصًا للتكامل المستمر. في هذه المقالة سنتحدث عن مقياس قاعدة كود ياندكس ، حول نقل التطوير إلى مستودع واحد مع نهج قائم على الجذع للتطوير ، حول المهام التي يجب على نظام التكامل المستمر حلها للعمل بفعالية في مثل هذه الظروف.



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


العديد من المهام التي نحلها لا تحل في عالم مفتوح المصدر. لا يوجد MapReduce يعمل بشكل جيد على وحدات التخزين لدينا (أكثر من 5000 خادم) ومهامنا ، لا يوجد متعقب مهام يمكنه التعامل مع عشرات الملايين من التذاكر لدينا. هذا جذاب في Yandex - يمكنك القيام بأشياء رائعة حقًا.


لكننا نفقد الكفاءة بشكل خطير عندما نحل نفس المشاكل من جديد ، ونعيد صياغة الحلول الجاهزة ، مما يجعل التكامل بين المكونات صعبًا. من الجيد والملائم أن تفعل كل شيء بنفسك فقط في زاويتك الخاصة ، لا يمكنك التفكير في الآخرين في الوقت الحالي. ولكن بمجرد أن تصبح الخدمة ملحوظة بما فيه الكفاية ، سيكون لها تبعيات. يبدو فقط أن الخدمات المختلفة تعتمد بشكل ضعيف على بعضها البعض ، في الواقع - هناك الكثير من الروابط بين أجزاء مختلفة من الشركة. تتوفر العديد من الخدمات من خلال تطبيق Yandex / Browser / إلخ ، أو مضمنة في بعضها البعض. على سبيل المثال ، تظهر أليس في المتصفح ، باستخدام أليس يمكنك طلب سيارة أجرة. نستخدم جميعًا مكونات مشتركة: YT و YQL و Nirvana .


كان لنموذج التنمية القديم مشاكل كبيرة. نظرًا لوجود العديد من المستودعات ، يصعب على المطور العادي ، وخاصة المبتدئ ، معرفة:


  • أين المكون؟
  • كيف يعمل: لا توجد طريقة "لأخذ وقراءة"
  • من يقوم بتطويره ودعمه الآن؟
  • كيف تبدأ استخدامه؟

ونتيجة لذلك ، نشأت مشكلة الاستخدام المتبادل للمكونات. لم تتمكن المكونات تقريبًا من استخدام مكونات أخرى لأنها تمثل "مربعات سوداء" لبعضها البعض. وقد أثر ذلك سلبًا على الشركة ، حيث لم يتم إعادة استخدام المكونات فحسب ، بل لم تتحسن في كثير من الأحيان. تم تكرار العديد من المكونات ، وكان حجم التعليمات البرمجية التي يجب دعمها ينمو بشكل ملحوظ. تحركنا بشكل عام أبطأ مما نستطيع.


مستودع واحد والبنية التحتية


منذ 5 سنوات ، بدأنا مشروعًا لنقل التطوير إلى مستودع واحد ، مع أنظمة مشتركة للتجميع والاختبار والنشر والمراقبة.


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


نتيجة للمشروع ، نشأت مجموعة واحدة من تقنيات البنية التحتية للشركة: تخزين التعليمات البرمجية المصدر ، نظام مراجعة التعليمات البرمجية ، نظام البناء ، نظام التكامل المستمر ، النشر ، المراقبة.


الآن يتم تخزين معظم التعليمات البرمجية المصدر لمشاريع Yandex في مستودع واحد ، أو أنها في طريقها إلى الانتقال إليها:


  • يعمل أكثر من 2000 مطور على المشاريع.
  • أكثر من 50000 مشروع ومكتبة.
  • يتجاوز حجم المستودع 25 غيغابايت.
  • وقد تم بالفعل الالتزام بأكثر من 3،000،000 التزام في المستودع.

الإيجابيات للشركة:


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

يجب أن يُفهم أيضًا أن نموذج التنمية هذا له عيوب يجب أخذها في الاعتبار:


  • يتطلب المستودع المشترك بنية تحتية منفصلة ومحددة.
  • قد لا تكون المكتبة التي تحتاجها في المستودع ، ولكنها مفتوحة المصدر. هناك تكاليف لإضافتها وتحديثها. تعتمد بشكل كبير على اللغة والمكتبة ، في مكان ما مجاني تقريبًا ، وفي مكان ما مكلف للغاية.
  • أنت بحاجة إلى العمل باستمرار على "صحة" التعليمات البرمجية. وهذا يشمل على الأقل مكافحة التبعيات غير الضرورية والرمز الميت.

نهجنا لمستودع مشترك يفرض قواعد عامة يجب على الجميع اتباعها. في حالة استخدام مستودع واحد ، يتم وضع قيود على اللغات المستخدمة والمكتبات وطرق النشر. ولكن في المشروع المجاور ، سيكون كل شيء مماثلاً أو مشابهًا جدًا لك ، ويمكنك حتى إصلاح شيء هناك.


إن نموذج المستودع المشترك ينجذب إلى جميع الشركات الكبيرة. يعد المستودع المترابط موضوعًا كبيرًا ومدروسًا ومناقشًا جيدًا ، لذلك لن نتطرق إليه كثيرًا. إذا كنت ترغب في معرفة المزيد ، فستجد في نهاية المقالة العديد من الروابط المفيدة التي تكشف عن هذا الموضوع بمزيد من التفاصيل.


الظروف التي يعمل فيها نظام التكامل المستمر


يتم التطوير وفقًا لنموذج التطوير المستند إلى الجذع. يعمل معظم المستخدمين مع HEAD ، أو أحدث نسخة من المستودع ، التي تم الحصول عليها من الفرع الرئيسي يسمى trunk ، حيث يتم التطوير. يتم تنفيذ التغييرات على المستودع بالتسلسل. مباشرة بعد التنفيذ ، يكون الرمز الجديد مرئيًا ويمكن لجميع المطورين استخدامه. لا يتم تشجيع التطوير في الفروع المنفصلة ، على الرغم من أنه يمكن استخدام الفروع للإصدارات.


تعتمد المشاريع على شفرة المصدر. تشكل المشاريع والمكتبات رسمًا بيانيًا معقدًا للاعتماد. وهذا يعني أن التغييرات التي تم إجراؤها في مشروع واحد من المحتمل أن تؤثر على باقي المستودع.


يذهب عدد كبير من الالتزامات إلى المستودع:


  • أكثر من 2000 التزام في اليوم الواحد.
  • ما يصل إلى 10 تغييرات في الدقيقة خلال ساعات الذروة.

تحتوي قاعدة الكود على أكثر من 500000 هدف واختبار بناء.


بدون نظام خاص من التكامل المستمر في مثل هذه الظروف ، سيكون من الصعب للغاية المضي قدما بسرعة.


نظام تكامل مستمر


يطلق نظام التكامل المستمر التجميعات والاختبارات لكل تغيير:


  • فحوصات أولية. أنها تسمح بفحص الرمز قبل ارتكاب وتجنب كسر الاختبارات في الجذع. يتم بعد ذلك تشغيل التجميعات والاختبارات أعلى HEAD. في الوقت الحالي ، تبدأ فحوصات ما قبل التدقيق بشكل طوعي. بالنسبة للمشروعات المهمة ، يلزم إجراء فحوصات ما قبل المراجعة.
  • الشيكات اللاحقة للالتزام بعد الالتزام بالمستودع.

تعمل الإصدارات والاختبارات بالتوازي على مجموعات كبيرة من مئات الخوادم. يبني واختبارات تعمل على منصات مختلفة. تحت المنصة الرئيسية (لينكس) ، يتم تجميع جميع المشاريع وتشغيل جميع الاختبارات ، تحت المنصات الأخرى - مجموعة فرعية من المشاريع القابلة للتكوين من قبل المستخدم.


بعد استلام وتحليل نتائج التجميعات وتشغيل الاختبارات ، يتلقى المستخدم ملاحظات ، على سبيل المثال ، إذا كانت التغييرات تكسر أي اختبارات.




في حالة فشل أو اختبارات التجميع الجديدة ، نرسل إشعارًا إلى مالكي الاختبار ومؤلف التغييرات. يقوم النظام أيضًا بتخزين نتائج الشيكات وعرضها في واجهة خاصة. تعرض واجهة الويب لنظام التكامل تقدم ونتائج الاختبار ، مقسمة حسب نوع الاختبار. قد تبدو الشاشة التي تحتوي على نتائج المسح الضوئي كما يلي:




ميزات وقدرات نظام التكامل المستمر


من خلال حل المشكلات المختلفة التي تواجه المطورين والمختبرين ، قمنا بتطوير نظامنا للتكامل المستمر. يحل النظام بالفعل العديد من المشاكل ، ولكن لا يزال هناك الكثير من التحسينات.


أنواع وأحجام الاختبارات


هناك عدة أنواع من الأهداف التي يمكن أن يؤدي إليها نظام التكامل المستمر:


  • تكوين. مرحلة التكوين التي يقوم بها نظام البناء. يتضمن التكوين تحليلاً لملفات التكوين لنظام التجميع ، وتحديد التبعيات بين المشاريع ومعلمات التجميع وتشغيل الاختبارات.
  • بناء. تجميع المكتبات والمشاريع.
  • النمط. في هذه المرحلة ، يتطابق نمط الكود مع المتطلبات المحددة.
  • اختبار. تنقسم الاختبارات إلى مراحل حسب مهلة وقت العمل ومتطلبات موارد الحوسبة.
    • صغير. <دقيقة واحدة
    • متوسط. <10 دقائق
    • كبير. > 10 دقائق بالإضافة إلى ذلك ، قد تكون هناك متطلبات خاصة لموارد الحوسبة.
    • كبير جدا. هذا هو نوع خاص من الاختبار. تتميز هذه الاختبارات بمجموعة من الخصائص التالية: وقت تشغيل طويل ، واستهلاك كبير للموارد ، وكمية كبيرة من بيانات المدخلات ، وقد تتطلب وصولًا خاصًا ، والأهم من ذلك ، دعم سيناريوهات الاختبار المعقدة الموضحة أدناه. هناك عدد أقل من هذه الاختبارات مقارنة بالأنواع الأخرى من الاختبارات ، لكنها مهمة جدًا.

اختبار تردد التشغيل واكتشاف الأعطال الثنائية


يتم تخصيص موارد ضخمة للاختبار في Yandex - المئات من الخوادم القوية. ولكن حتى مع وجود عدد كبير من الموارد ، لا يمكننا إجراء جميع الاختبارات لكل تغيير يؤثر عليها. ولكن في الوقت نفسه ، من المهم جدًا بالنسبة لنا أن نساعد المطور دائمًا على توطين المكان الذي ينقطع فيه الاختبار ، خاصة في مثل هذا المستودع الكبير.


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




عند بدء فحوصات ما قبل التدقيق ، نقوم أيضًا بتشغيل التجميعات واختبارات الضوء. ثم يمكن للمستخدم بدء إطلاق الاختبارات الثقيلة يدويًا عن طريق الاختيار من قائمة الاختبارات المتأثرة بالتغييرات التي يوفرها النظام.


كشف اختبار وامض


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


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

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


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


التحديث التلقائي لمدخلات الاختبار


عند اختبار أنظمة ياندكس الأكثر تعقيدًا ، بالإضافة إلى طرق الاختبار الأخرى ، غالبًا ما يُستخدم اختبار إستراتيجية الصندوق الأسود + الاختبار المعتمد على البيانات . لضمان تغطية جيدة ، تتطلب هذه الاختبارات مجموعة كبيرة من بيانات الإدخال. يمكن اختيار البيانات من مجموعات الإنتاج. لكن هناك مشكلة في حقيقة أن البيانات تصبح بسرعة قديمة. العالم لا يقف ساكنا ، وأنظمتنا تتطور باستمرار. لن توفر بيانات الاختبار القديمة بمرور الوقت تغطية اختبار جيدة ، ومن ثم تؤدي تمامًا إلى انهيار الاختبار نظرًا لأن البرامج تبدأ في استخدام بيانات جديدة غير متوفرة في بيانات الاختبار القديمة.


لكي لا تصبح البيانات قديمة ، يمكن لنظام التكامل المستمر تحديثها تلقائيًا. كيف يعمل؟


  1. يتم تخزين بيانات الاختبار في مخزن خاص للموارد.
  2. يحتوي الاختبار على بيانات وصفية تصف المدخلات المطلوبة.
  3. يتم تخزين المراسلات بين مدخلات وموارد الاختبار المطلوبة في نظام تكامل مستمر.
  4. يوفر المطور تسليمًا منتظمًا للبيانات الجديدة إلى متجر الموارد.
  5. يبحث نظام التكامل المستمر عن إصدارات جديدة من بيانات الاختبار في مستودع الموارد ويبدل بيانات الإدخال.

من المهم تحديث البيانات حتى لا يتم إجراء الاختبار الخاطئ. لا يمكنك فقط أخذ ، وبدءًا من التزام معين ، ابدأ في استخدام بيانات جديدة ، لأنه في حالة حدوث انهيار تجريبي ، لن يكون من الواضح من يقع اللوم - الالتزام أو البيانات الجديدة. كما سيجعل اختبارات الاختلاف (الموضحة أدناه) معطلة.



لذلك ، نجعلها بحيث يكون هناك بعض الفواصل الزمنية الصغيرة للالتزامات ، والتي يتم بدء الاختبار عليها مع الإصدارات القديمة والجديدة من بيانات الإدخال.




اختبارات مختلفة


اختبارات الاختلاف نسمي نوعًا خاصًا من الاختبارات التي تعتمد على البيانات ، والتي تختلف عن النهج المقبول بشكل عام من حيث أن الاختبار ليس له نتيجة مرجعية ، ولكن في نفس الوقت نحتاج إلى العثور على ما يجعل الاختبار يغير سلوكه.


النهج القياسي في الاختبار القائم على البيانات هو كما يلي. حصل الاختبار على نتيجة مرجعية عند تشغيل الاختبار لأول مرة. يمكن تخزين النتيجة المرجعية في المستودع بجوار الاختبار. يجب أن ينتج عن الاختبارات اللاحقة نفس النتيجة.



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


هناك صعوبات عند استخدام هذا النهج في مستودع كبير مع تدفقات كبيرة الالتزام:


  1. يمكن أن يكون هناك العديد من الاختبارات والاختبارات يمكن أن تكون صعبة للغاية. لا يمتلك المطور القدرة على تشغيل جميع الاختبارات المتأثرة في بيئة عمل.
  2. بعد إجراء التغييرات ، قد ينكسر الاختبار إذا لم يتم تحديث النتيجة المرجعية في وقت واحد مع التغييرات على الرمز. ثم يمكن لمطور آخر إجراء تغييرات على نفس المكون وستتغير نتيجة الاختبار مرة أخرى. نحصل على فرض خطأ على آخر. من الصعب جدًا التعامل مع مثل هذه المشاكل ، فهي تستغرق وقتًا من المطورين.

ماذا نفعل. تتكون اختبارات Diff من جزأين:


  • تحقق من المكون.
    • نبدأ الاختبار وحفظ النتيجة في تخزين الموارد.
    • لا تقارن النتيجة مع المرجع.
    • يمكننا التقاط بعض الأخطاء ، على سبيل المثال ، لا يبدأ البرنامج / لا ينتهي ، يتعطل ، لا يستجيب البرنامج. يمكن أيضًا التحقق من صحة النتيجة: وجود أي حقول في الإجابة ، إلخ.
  • مكون مختلف.
    • مقارنة النتائج التي تم الحصول عليها في عمليات الإطلاق المختلفة وإنشاء فرق. في أبسط الحالات ، هذه وظيفة تأخذ معلمتين وتعيد فرقًا.
    • يعتمد مظهر الاختلاف على الاختبار ، ولكن يجب أن يكون شيئًا مفهومًا لشخص سيبحث في الاختلاف. عادة ما يكون الاختلاف هو ملف html.

يتم التحكم في إطلاق مكونات الفحص والتباين بواسطة نظام تكامل مستمر.




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


يتبع


في المقالة التالية سنتحدث عن كيفية عمل نظام التكامل المستمر.


المراجع


مستودع متآلف ، تطوير قائم على جذع



اختبار مدفوع بالبيانات


Source: https://habr.com/ru/post/ar428972/


All Articles