CI/CD لبنيات الخدمات الصغيرة

Azure

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

ما هو التكامل المستمر والتسليم المستمر؟

عندما نتحدث عن التكامل المستمر والتسليم المستمر، فإننا نتحدث حقاً عن العديد من العمليات ذات الصلة: التكامل المستمر، والتسليم المستمر، والتوزيع المستمر.

  • التكامل المستمر. كثيرا ما يتم دمج تغييرات التعليمة البرمجية في الفرع الرئيسي. تضمن عمليات البناء والاختبار ذات التنفيذ التلقائي أن التعليمة البرمجية في الفرع الرئيسي دائماً ما تكون بجودة الإنتاج.

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

  • التوزيع المستمر. يتم تلقائياً توزيع تغييرات التعليمة البرمجية التي تمرر الخطوتين السابقتين في الإنتاج.

فيما يلي بعض أهداف عملية التكامل المستمر/التسليم المستمر القوية لبنية الخدمات المصغرة:

  • يمكن لكل فريق بناء وتوزيع الخدمات التي يمتلكها بشكل مستقل، دون التأثير على الفرق الأخرى أو تعطيلها.

  • قبل توزيع إصدار جديد من الخدمة للإنتاج، يتم توزيعه في بيئات التطوير/الاختبار/ضمان الجودة للتحقق من صحتها. يتم فرض بوابات الجودة في كل مرحلة.

  • يمكن توزيع إصدار جديد من الخدمة جنباً إلى جنب مع الإصدار السابق.

  • وجود نُهج كافية للتحكم في الوصول.

  • بالنسبة لأحمال العمل المعبأة في حاويات، يمكنك الوثوق بصور الحاوية التي تم توزيعها في الإنتاج.

لماذا يعتبر تدفق التكامل المستمر/التسليم المستمر قوياً مهماً

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

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

رسم تخطيطي لمتجانس CI/CD

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

التحديات

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

    التخفيف: احصل على تدفق موحد وآلي لبناء وتوزيع الخدمات، بحيث لا تكون هذه المعرفة "مخفية" داخل كل فريق.

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

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

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

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

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

  • تحديثات الخدمة. عندما تقوم بتحديث خدمة إلى إصدار جديد، فلا ينبغي أن تؤدي إلى تعطيل الخدمات الأخرى التي تعتمد عليها.

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

Monorepo مقابل متعدد الريبو

قبل إنشاء سير عمل التكامل المستمر/التسليم المستمر، يجب أن تعرف كيف ستتم هيكلة قاعدة التعليمة البرمجية وإدارتها.

  • هل تعمل الفرق في مستودعات منفصلة أم في monorepo (مستودع واحد)؟
  • ما هي إستراتيجيتك المتفرعة؟
  • من يمكنه دفع التعليمة البرمجية إلى الإنتاج؟ هل هناك دور مدير التحرير؟

لقد حظي نهج monorepo بتأييد ولكن هناك مزايا وعيوب لكليهما.

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

خدمات التحديث

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

المتداول التحديثات

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

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

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

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

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

نشر أزرق أخضر

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

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

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

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

إصدار Canary

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

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

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

الخطوات التالية