فريقنا مسؤول عن تشغيل وتطوير منتج الشركات الكبيرة.
في بداية عام 2017 ، بعد أخذ استراحة من تنفيذ رئيسي وإعادة قراءة "الدروس المستفادة" ، قررنا بشدة مراجعة تطوير وتقديم تطبيقنا. كنا قلقين بشأن السرعة المنخفضة وجودة التسليم ، ولا نسمح لنا بتقديم مستوى الخدمة الذي يتوقعه العملاء منا.
لقد حان الوقت للانتقال من الكلمات إلى الأفعال - لتغيير العمليات.
ستتحدث هذه المقالة بإيجاز عن المكان الذي بدأنا فيه ، وما فعلناه ، وما هو الوضع الآن ، والصعوبات التي واجهناها ، وما الذي يجب أن نتركه وراءنا ، وما الذي نخطط للقيام به أيضًا.
ابدأ
القليل عن النظام
التطبيق هو مثال كلاسيكي لتطبيق مؤسسي مترابط من "الانسكاب المعماري في 2000s":
- تعمل وتم تطويرها على مدى 15 عامًا.
- وهي عبارة عن مجموعة من ستة عشر WinForms وخدمات Windows وتطبيقات ASP. ASP مرتبطة بقاعدة بيانات MS SQL واحدة ونصف.
- حجم قاعدة التعليمات البرمجية: ~ 1MLOC لـ C # ، ~ 9000 كائنات قاعدة البيانات. يتم تشغيل الكثير من منطق الأعمال على جانب قاعدة البيانات.
- يتكون التطبيق من ~ 250 + حلول لإنشاء عميل win / web (حل واحد لكل مجموعة من النماذج ذات الصلة). هذا هو إرث عملية التطوير السابقة وبنية العميل.
- يدعم التطبيق عدة أنواع من العمليات (العملاء) عن طريق تغيير التكوين الداخلي: تعيين العمليات والأذونات والحقول المرنة ، وما إلى ذلك ، في جداول تكوين قاعدة بيانات النظام. في نفس الوقت ، قاعدة رمز التطبيق هي نفسها لجميع العملاء.
- يتم نشر التطبيق ودعمه في أكثر من 25 موقعًا (كل موقع هو نسخة مستقلة من النظام) ويخدم ما مجموعه عدة آلاف من المستخدمين النهائيين في مناطق زمنية مختلفة.
- يتم تنفيذ وتجميع التطبيق النهائي ومكوناته من قبل المقاول.
- تم تخزين الكود على جانب المقاول (النسخة المحلية من MS TFS). يتم إرسال الرمز إلى العميل على أساس شهري في شكل أرشيف للنسخة الحالية من فرع المستودع الرئيسي.
- تم التسليم عن طريق تسليم "تحديثات دلتا": للتطبيق (مجموعة dll ، exe ، إلخ) ومكونات قاعدة البيانات (مجموعة من سكربت سكول إنشاء / تغيير). تم بناء التطبيق وتحضير حزم دلتا من قبل المقاول.
- تم دعم عملية النشر بواسطة نظام النقل ، وتم تطبيق التغييرات تلقائيًا.
يتم التسليم كجزء من الإصدارات الشهرية (كما قمت بترتيبها ، أخبرتك سابقًا هنا ).
المشاكل الموجودة
عدم السيطرة
- على الرغم من الملكية الرسمية للرمز ، كان التجميع الفعلي للتطبيق من قبل العميل مستحيلاً.
- نتيجة لذلك ، من المستحيل التحقق من قابلية تشغيل الكود المرسل للعميل.
- التغييرات في التعليمات البرمجية - ليست شفافة للعميل. لا يمكن مطابقة التغييرات المطلوبة والفعلية في المنتج.
- يعد تحليل التعليمات البرمجية صعبًا بالنسبة لـ SQL ، وهو مستحيل بالنسبة لمكونات C #
المدخلات والأخطاء العمل
- يعد إعداد "حزم دلتا" إجراءً يستغرق وقتًا طويلاً في التنمية ومصدرًا للأخطاء وبعض تكاليف المشروع.
- يتطلب نشر تطبيق Delta Packet تتبع ترتيب الحزم. يُعد الخطأ خارج الترتيب للحزمة مشكلة نشر رئيسية ومصدرًا مهمًا للحوادث.
- تحدث الانحدارات بانتظام: ظهرت الأخطاء التي يبدو أنه تم إصلاحها وطرح تصحيحات للمنتج مرة أخرى.
القيود
- إن القدرة على استعادة حالة النظام في وقت ما في الماضي (تغييرات التراجع) غائبة تقريبًا.
- إن القدرة على توسيع نطاق التطوير والاختبار المبكر من خلال جذب موظفي العملاء غائبة عمليا.
النتائج المتوقعة
في بداية المشروع ، وضعنا أهدافًا واضحة لنا لحل المشاكل المحددة أعلاه.
- نقل مستودع رمز لمراقبة العملاء
- انقل عملية إنشاء التطبيق إلى جانب العميل
- تعديل عملية توزيع التغييرات ، مع التخلي عن "دلتا التغييرات" لصالح التحديث الكامل
بالإضافة إلى ذلك ، باستخدام الحلول التي تم الحصول عليها عند تحقيق الهدفين الأولين ، قمنا بحساب:
- تحسين الجودة التقنية للحلول الناتجة من خلال التحكم في التعليمات البرمجية
- زيادة المشاركة الاختبارية وسهولة الاستخدام من خلال توفير نشر الخدمة الذاتية.
مراحل الطريق الطويل
تحليل الوضع الحالي لعمليات التنمية
الخطوة الأولى: تحليل عملية تطوير المقاول الحالية. وقد ساعد ذلك على تخطيط التغييرات بحيث لا يقاطع العمل إن أمكن.
لسوء الحظ ، أظهر التعرف على عملية التطوير أنه في فهم صناعة تكنولوجيا المعلومات في الوقت الحاضر ، كانت العملية غائبة.
- لم يتم الاحتفاظ برمز قاعدة البيانات ومنطق الأعمال الخاص بها في المستودع حتى الآن. السبب الرئيسي: قلة الأدوات التي تنفذ التجميع من الكود في المستودع ونشر النتيجة. لذا ، فإن الرمز الموجود في المستودع هو مجرد وثائق.
- النسخة "الحقيقية" لرمز قاعدة البيانات موجودة في "قاعدة بيانات التطوير" الشائعة ، والتي يعمل عليها عشرات المطورين.
- تم الاحتفاظ برمز تطبيق العميل (C # ، ASP.NET) في المستودع ، ولكن لم يتم ضمان جودة وتوقيت عمليات الالتزام.
- تم تجميع المكونات (وليس التطبيق بالكامل) في محطات المطورين. ليس من الواضح تمامًا كيف تم تحديث الرمز قبل التجميع. تم وضع المكون المجمع في مجلد مشترك مشترك. من هناك ، تم تشكيل "حزمة دلتا" للعميل.
- النقص الكامل في ممارسة الحفاظ على فروع التنمية. من خلال الإشارات غير المباشرة ، اشتبهنا في ذلك لفترة طويلة - ولكن بعد الغوص في العملية ، أصبح كل شيء واضحًا.
التحول إلى مستودع جديد ونظام تحكم الإصدار
تحديد الاعتماد على منصات MS ومعايير الشركات اختيار بيئة التطوير - Team Foundation Server.
ومع ذلك ، في الوقت الذي بدأنا فيه المشروع مباشرة (أبريل 2017) ، تم إصدار إصدار Visual Studio Team Services للتو. بدا المنتج مثيرًا للاهتمام للغاية ، حيث تم تعيينه كإتجاه استراتيجي لـ MS ، حيث قدم مستودعات git ، والتجميع والنشر لـ on-prem و cloud.
تخلفت TFS للشركات المحلية عن إصدار ووظيفة VSTS ، وكان الانتقال إلى الإصدار الجديد قيد المناقشة فقط. لم نرد الانتظار. قررنا التبديل على الفور إلى VSTS ، حيث أدى ذلك إلى خفض تكاليفنا العامة لدعم النظام الأساسي وزودنا بالتحكم الكامل في كيف وماذا نفعل.
في وقت بداية التغييرات ، كان لدى فريق التطوير خبرة في TFSVC ، تم تخزين رمز التطبيق في مثل هذا المستودع. من ناحية أخرى ، أصبحت GIT منذ فترة طويلة المعيار لمجتمع تكنولوجيا المعلومات - أوصى العملاء والمستشارون من الجهات الخارجية بالتبديل إلى هذا النظام.
أردنا أن يشارك فريق التطوير في اتخاذ قرار بشأن نظام جديد للتحكم في الإصدار ، واتخاذ قرار مستنير.
نشرنا مشروعين في VSTS مع مستودعات مختلفة - TFSVC و GIT. تم تحديد مجموعة من السيناريوهات التي تم اقتراحها لاختبار وتقييم قابلية الاستخدام في كل نظام.
من بين السيناريوهات التي تم تقييمها كانت:
- إنشاء ودمج الفروع
- تنظيم العمل المشترك (في فرع واحد أو مختلف)
- عمليات سلسلة التغيير (الالتزام ، التراجع)
- تكامل الطرف الثالث
- القدرة على متابعة العمل عند عدم توفر الخادم.
ونتيجة لذلك ، كما هو متوقع ، تم اختيار GIT ، ولم يندم عليه أحد حتى الآن.
كعملية ، بدأنا باستخدام GitFlow. وفرت هذه العملية تحكمًا كافيًا في التغييرات وسمحت بتسليم الإصدارات ، كما اعتدنا عليه.
- دافعنا عن فرع التطوير بسياسة تتطلب أن تمر جميع التغييرات بطلبات السحب.
- نحاول الالتزام بممارسة "تذكرة واحدة - طلب سحب واحد". لا يتم دمج التغييرات من تذاكر مختلفة في تغيير واحد. نحن نحاول أن نبذل قصارى جهدنا للاختبار على فرع الميزة لتجنب الموقف مع التصحيحات في عمليات السحب اللاحقة.
- عند الاندماج في التطوير ، يتم دمج جميع التغييرات في التزام واحد (الاسكواش).
- يتم إنشاء فروع الإصدار من تطوير.
- إذا لزم الأمر ، في فرع الإصدار ، يمكنك إضافة أحدث التغييرات بشكل انتقائي (اختيار الكرز) أو جميع (إعادة التحديد). نحن لا نقوم بالتصحيح مباشرة في فرع التحرير.
- بعد نشر الإصدار الأخير على المنتج ، يتم إتقانه عن طريق قوة الدفع (فقط عدد قليل من الأشخاص لديهم هذا الحق)
أتمتة تجميع المنتج
كان التطبيق عبارة عن عدد كبير من التجمعات ، مئات الحلول. كما اتضح أثناء تدقيق العملية ، تم جمع كل هذا بشكل منفصل و "يدويًا".
في المرحلة الأولى ، قررنا عدم إعادة كل شيء من البداية (حتى لا يتم إيقاف التسليم الحالي) ، ولكن "لف" التجميع في مجموعة من نصوص msbuild - نص برمجي واحد لكل مكون.
وبالتالي ، حصلنا بسرعة على نصوص برمجية نفذت جميع القطع الأثرية الوسيطة اللازمة ، وفي النهاية - المنتج النهائي.
قصة منفصلة هي تصميم قاعدة بيانات. لسوء الحظ ، يحتوي النظام على العديد من مكونات CLR التي لم تكن منظمة بشكل جيد. التبعيات لا تسمح بقاعدة نشر بسيطة مع المحتوى. في الوقت الحالي ، يتم حل هذه المشكلة بواسطة نص برمجي سابق للنشر.
بالإضافة إلى ذلك ، نظرًا لطبيعة النظام غير المتكافئة (تم تثبيت إصدارات SQL Server 2008 و 2014 في نقاط مختلفة) ، كان من الضروري تنظيم تجميع المشروع الأساسي للإصدارات .Net 2.0 و 4.0.
بعد أن تم تجهيز جميع البرامج النصية واختبارها ، تم استخدامها في نص البرنامج النصي VSTS.
مباشرة قبل بدء التجميع ، تم تحديث إصدارات جميع المنتجات إلى رقم قياسي مشترك ، بما في ذلك رقم البناء من البناء. تم تخزين نفس الرقم في البرنامج النصي بعد النشر. وهكذا ، جاءت جميع المكونات - قاعدة البيانات وجميع تطبيقات العميل - متسقة ومرقمة على حد سواء.
النشر إلى منصة الاختبار
بعد اكتمال الإصدار الأولي من عملية البناء ، تابعنا في إعداد البرنامج النصي للنشر.
ومن المتوقع أن قاعدة البيانات كانت الأكثر إثارة للقلق.
كشف نشر نسخة "عليا" من قاعدة بيانات حقيقية عن العديد من التضارب بين التجميع وحالة الأنظمة الحقيقية:
- إصدارات غير متناسقة في GIT وفي النظام الحقيقي
- مخططات قواعد البيانات المملوكة للمستخدمين الذين تم التخطيط لحذفهم.
استقرار عملية التنمية
بالطبع ، من الغريب أن نتحدث عن هذا ، والأكثر من ذلك أن أكتب هنا ، ولكن التغيير الأكثر خطورة للمطورين كان تقديم مبدأ "إذا لم يكن هذا في بوابة ، فهذا غير موجود." في السابق ، تم الالتزام بالرمز "لإبلاغ العميل". الآن - بدون هذا ، من المستحيل تقديم أي شيء.
كان أصعب شيء مع رمز قاعدة البيانات. بعد التبديل إلى نشر قاعدة البيانات من المستودع ، من خلال التجميع والنشر باستخدام sqlpackage ، تم استبدال نهج "دلتا" بنهج "الحالة المرغوبة". كانت الحزم شيئًا من الماضي ؛ كان يجب نشر كل شيء تلقائيًا.
لكن! حتى الانتقال الكامل إلى عملية النشر الجديدة ، لا تزال هناك حاجة لتسليم التغييرات. وكان من الضروري القيام بذلك بالطريقة القديمة - "تحديثات دلتا".
لقد واجهنا مهمة ضمان الاتساق الكامل والثابت لحالة النظام عند تسليم حزم دلتا ومحتويات المستودع.
للقيام بذلك ، قمنا بتنظيم العملية التالية:
- بانتظام ، تم جمع التعليمات البرمجية من المستودع ونشرها في قاعدة بيانات "نموذج" فارغة.
- على أساس قاعدة "النموذج" ، تم إعداد اختبار آلي خاص. تم حساب المجموع الاختباري لكل عنصر في قاعدة بيانات "النموذج". الاختبار التلقائي يحتوي على كل هذه المجموع الاختباري وعند بدء التشغيل يقوم بحساب المجموع الاختباري للكائنات المقابلة لقاعدة البيانات "المحددة". يؤدي أي اختلاف في تكوين الأشياء أو المجموع الاختباري إلى انخفاض في الاختبار.
- يحظر اختبار "السقوط" تلقائيًا نقل الطرود من بيئة الاختبار إلى أسفل المشهد. وقد تم تنفيذ هذا التكامل بالفعل في نظام النقل السابق.
وبالتالي ، باستخدام التحكم التلقائي ، كان من الممكن تقديم رمز قاعدة بيانات المنتج بشكل سريع نسبيًا والحفاظ عليه دون جهد إضافي من جانب فريق المشروع. في الوقت نفسه ، بدأ المطورون في التعود على الحاجة إلى الالتزام بالتعليمات البرمجية في المستودع بشكل صحيح وفي الوقت المناسب.
نشر المنتج في بيئات اختبار التكامل
بعد الانتهاء من المرحلة السابقة ، شرعنا مباشرة في نشر التطبيق في بيئة اختبار. لقد توقفنا تمامًا عن تطبيق حزم دلتا لاختبار الأنظمة وتحولنا إلى النشر التلقائي باستخدام VSTS.
منذ تلك اللحظة ، بدأ الفريق بأكمله في تلقي الثمار الأولى للجهود التي بذلت في وقت سابق: تم النشر دون أي جهود إضافية. تم جمع الرمز المخصص ونشره واختباره تلقائيًا.
لسوء الحظ ، كما فهمنا لاحقًا ، أدت "محاذاة المستودع" إلى حقيقة أن لدينا نسخة من النسخة المدعومة بثبات من "التطوير" ، ولكن إصدار "الإنتاج" لا يزال غير متاح. وبالتالي ، لم يكن هناك شيء يتجاوز بيئة الاختبار مع QAS و PRD.
يمكن مقارنة كود التطبيق على جانب قاعدة البيانات مع رمز المنتج وفهم الاختلافات. لم يكن هناك شيء لمقارنة تطبيقات العملاء به - لم يكن هناك سوى نسخة منتجة محدثة في شكل مجموعة من الملفات القابلة للتنفيذ ، والتي تم تجميعها منها كان من المستحيل القول بالتأكيد.
اختبار المنتج نتيجة التجميع التلقائي
بعد تغيير نهج التجميع ، كان على المنتج أن يخضع لاختبار انحدار مكثف. كان من الضروري التأكد من أن التطبيق يعمل ولم يتم فقدان أي شيء.
عند الاختبار ، تبين أنه أسهل مع الوظيفة الموجودة على جانب قاعدة البيانات. لحسن الحظ ، قمنا بتطوير مجموعة كبيرة من الاختبارات الذاتية التي تغطي المناطق الحرجة.
ولكن لم تكن هناك اختبارات لـ C # - لذلك ، تم فحص كل شيء يدويًا. كان هذا قدرًا كبيرًا من العمل ، واستغرق التحقق بعض الوقت.
قفزة الإيمان - النشر التجريبي الإنتاجي
على الرغم من الاختبار ، كان النشر على أحد المنتجات لأول مرة أمرًا مخيفًا.
كنا محظوظين - لقد خططنا للتو للنشر التالي للنظام في موقع جديد. وقررنا استخدام هذه الفرصة لنشر تجريبي.
لم يلاحظ المستخدمون ، كانت الأخطاء المحتملة للتجميع الجديد سهلة الإصلاح ، ولم يبدأ العمل المنتج الحقيقي بعد.
نشرنا النظام ، ولعدة أسابيع كان في وضع الاستخدام المسبق (تحميل منخفض ، نمط معين من الاستخدام يمكن تخطيه في المنتج). خلال هذا الوقت ، تم الكشف عن العديد من العيوب التي تم تفويتها أثناء الاختبار. قاموا بالتصحيح كما تم العثور عليهم ، وتم طرح الإصدار الجديد على الفور للتحقق.
بعد الإطلاق الرسمي وبعد أسبوع من الدعم بعد الإطلاق ، أعلنا أن هذه هي النسخة الأولى التي تم تجميعها وتسليمها "بطريقة جديدة".
أصبح هذا الإصدار من التجميع أول إصدار ثابت من الفرع الرئيسي ، حيث تم تعليقه بعلامات fisrt_deployment (لم نطلب رموزًا مع تجزئة الالتزام).
نشر مقياس عبر المشهد الإنتاجي بأكمله
كما قال جيمس بوند: "المرة الثانية أبسط بكثير". بعد نجاح النشر التجريبي ، قمنا بسرعة بتوصيل المثيلات المتبقية من أنظمة من نفس النوع.
لكن لدى النظام عدة أنواع من الاستخدام - يمكن استخدام وظيفة واحدة لنوع واحد ، ولا تستخدم في حالات أخرى. وبناءً على ذلك ، فإن الوظيفة المختبرة عند تنفيذ النوع الأول لا تضمن بالضرورة النجاح في حالات أخرى.
لاختبار وظائف أنواع الاستخدام المتبقية ، بدأنا في استخدام المشاريع النشطة التي كانت قيد التطوير. كانت الفكرة متشابهة وتم النشر الأول - بدأنا في استخدام التجميعات التلقائية و "تمريرها" إلى المستخدمين إلى جانب وظيفة التصميم. وهكذا ، قام المستخدمون ، الذين يعملون مع إصدار "المشروع" للمنتج ، في نفس الوقت بفحص الوظائف القديمة.
كشف التحجيم نفسه عن مشاكل فنية غير متوقعة:
منظر نظام غير متجانس
بالإضافة إلى نشر التطبيق مباشرة ، كان علينا أن نحرص أولاً على أن كل شيء كان على حاله في كل مكان - إصدارات Net و Powershell والوحدات النمطية. استغرق الأمر كله قدرًا لا بأس به من الوقت.
اتصال الشبكة
في بعض المواقع ، لم يسمح اتصال الشبكة ببساطة بضخ جميع مكونات التجميع. كانت هناك مهلات ، تلف أثناء النقل. لقد فحصنا وحاولنا الكثير من الأشياء - ليس بنجاح كبير.
كان علي أن أتطرق إلى الحل التالي: تم الانتهاء من البرنامج النصي للبناء بحيث تم تجميع جميع النتائج في أرشيف واحد كبير ، ثم تم تقطيعه إلى أجزاء صغيرة (2 ميغابايت لكل منها). لقد انتهينا من سيناريو النشر لإزالة التزامن عند تنزيل القطع الأثرية ، وقبلنا جميع أجزاء 2 ميجابايت واستعادنا منها ما يمكن توسيعه بالفعل.
الصراع مع مكافحة الفيروسات
هناك مشكلة غريبة أخرى واجهناها هي الصراع بين برنامج مكافحة الفيروسات وأحد خطوات النشر: عندما يتم استخراج جميع أنواع الملفات "المشبوهة" ، مثل .js ، .dll ، من أرشيفات القطع الأثرية ، يبدأ برنامج مكافحة الفيروسات في النظر إليها عن كثب. والغريب في الأمر أن مضاد الفيروسات يبدأ في الاندفاع إلى الملف قبل نهاية عملية التفريغ ، وتسقط عملية التفريغ برسالة "الملف مشغول بعملية أخرى". بينما نكافح مع هذا ، باستثناء المجلد المحلي الذي يحتوي على آثار من الفحص ، فهو ليس جيدًا جدًا ، لكننا لم نتوصل إلى أي شيء آخر.
تحسين العملية
, " " — .
- (service-now.com) VSTS Work Items. develop — .
- CI feature . —
- "self-service"
- — . , .
- : , CI/CD ,
- ( )
- - ( ) . — , .
- VSTS , , .
الملخص
- MS VisualStudio Team Services ( — Azure Devops) . — GIT
- (/)
- git / GitFlow .
- code review .
- CI. , feature , .
- . , .
- ( ) — . - .
- - 1 . - .
- "" .
— 14
, , , .
, — 250 * .