
مقدمة
يوم جيد للجميع. أنا مطور بيثون في شركة تتعامل مع حلول معقدة لأتمتة العمليات التجارية ، وتطوير لحل المهام الفردية ، والتحليلات والاستشارات. تشمل مسؤولياتي تطوير وصيانة بنية الخدمات المصغرة. واليوم أود أن أخبرنا كيف نكافح مع الخدمات الدقيقة ولماذا التوحيد مهم للغاية بالنسبة لهم.
ليس سراً أن هذا النهج لتطوير المنتجات يستحوذ على السوق بشكل متزايد. وكلما غطسنا فيهم ، كلما كان من الضروري ألا ننسى القواعد الأساسية للعمل معهم. من أجل هيكلة تجربتنا في كتابة منتجات خدمات microservice ، تقرر كتابة سلسلة من المقالات حول كيفية تعميم بعض جوانب التطوير على جميع الخدمات.
واحدة من هذه القاعدة هو التوحيد. في شركتنا ، تتكون معظم المنتجات من مجموعة من اللغات والتقنيات المتنافرة. في كل هذا المقصود ، يجب عليك التفكير في كيفية تعميم المبادئ الأساسية على جميع الخدمات المصغرة لدعمها السهل وتكوينها وتطويرها المريح. سيتم مناقشة هذا في سلسلة هذه المقالات.
أطلب من جميع المهتمين تحت القط.
المشكلة
ربما يكون أول ما تصادفه في تطوير خدمة ما هو أساليب التكوين الخاصة بها. في بنية الخدمات الصغيرة ، تصبح هذه المشكلة أكثر حدة.
تخيل أن لديك عشرين خدمة وتحتاج إلى تغيير معلمة في كل منها. على سبيل المثال ، قم بتعطيل استخدام CORS. نظرًا لأن النظام متعدد المكونات ومبني على خدمات ميكروية ، فمن الأفضل استخدام نهج موحد لتكوين جميع الوحدات ، من أجل الإدارة المريحة. لذلك ، تحتاج إلى استخدام نفس الأسلوب عند إعداد كل وحدة نمطية.
يمكنك أن تقول أن مطور كل خدمة يجب أن يفعل ذلك ، لكن ماذا لو تم تخزين جميع التكوينات الخاصة بك في Kubernetes نفسه ، حيث لا يمكن منحها لجميع المطورين؟ سيضطر فقراء DevOps إلى قضاء الكثير من الوقت في تعلم الخدمات وطرق التكوين الخاصة بهم. وسيتم تكرار هذا الإجراء مع تحديث الخدمات ، خاصةً إذا كان هناك من يريد تجربة شيء جديد في إعدادات الخدمة. مع هذا النهج ، سيقضي الفريق باستمرار جزءًا من الوقت في العمل مع التكوينات ، وليس تطوير ميزات جديدة ، وإصلاح الأخطاء ، إلخ.
في هذه الحالة فقط ، هناك حاجة إلى تكوين عام لن يتم ربطه بلغة أو تقنية معينة وسيسمح لك بتكوين جميع الخدمات مع الحد الأدنى من الاختلافات في الهيكل العام للتكوين. لهذه المهمة ، قمنا بتطوير نظام لإعداد "الوحدات" (الخدمات) باستخدام ملفات yaml ، والقدرة على تخزين التكوينات لمراحل مختلفة (dev / prod / local وغيرها) وتقسيم الشيء كله إلى كتل مختلفة تتعلق بأشياء معينة.
المواصفات
يمكنك التحدث كثيرًا حول مكان وكيفية استخدامه ، لكنني أقترح الانتقال مباشرةً إلى مواصفات طريقة التكوين هذه. كما يقولون ، النظرية جيدة ، والممارسة أفضل.
متطلبات النظام
لنبدأ بتحديد نظامنا ومتطلباته.
- كل وحدة هي مكون مستقل في الحاوية
- يمكننا تمرير متغيرات البيئة إلى الحاوية
- لا يمكننا تغيير التكوين أثناء التنقل دون إعادة تشغيل الخدمة (إنشاء حاوية جديدة).
- يتم تنفيذ جميع الإجراءات الاحتياطية (مثل التبديل إلى قاعدة بيانات النسخ الاحتياطي) خارج المكون وتكون شفافة لها.
متطلبات طريقة التكوين
الآن دعونا نقرر ما نريد رؤيته من طريقة التكوين الخاصة بنا من أجل تلبية جميع المتطلبات.
- نوع ملف التكوين هو YAML للهيكل المحدد. تم اختيار YAML من قبلنا لعدة أسباب:
- القدرة على كتابة التعليقات وهيكل مناسب ، على عكس JSON
- القدرة على وصف المصفوفات على عكس ENV
- من خارج منطقة الجزاء يمكن استخدامها لإدراجها من القيم. yaml في رأس (Kubernetes)
- يجب دمج ملفات التكوين في شجرة التكوين
- يجب أن يكون التكوين خاصًا بالمرحلة. كل مرحلة لها مجموعة كاملة خاصة بها. هنا يجدر إبداء بعض التحفظات لتوضيح:
- لا يمكنك إعادة استخدام قيم المتغيرات من مرحلة أخرى ، باستثناء مرحلة الإعدادات الافتراضية ، والتي يتم تخصيصها للقيم الافتراضية.
- عند تحميل التكوين ، تحتاج إلى القيام بدمج متكرر لطبقة التكوين من المرحلة المحددة في أعلى الإعدادات الافتراضية مع أولوية طبقة المرحلة المحددة. لا ينبغي الجمع بين القيم (المصفوفات ، وما إلى ذلك).
- إذا كان هناك العديد من ملفات التكوين لمرحلة واحدة ، فيجب دمج المفاتيح فيها ، وبالتالي يجب أن تكون فريدة بالنسبة لبعضها البعض.
- يجب تحديد المرحلة الحالية المستخدمة بقيمة متغير البيئة "STAGE". تغيير المتغير في مثيل قيد التشغيل من خدمة غير مخصص.
- يجب تحديد المسار المطلق إلى دليل التكوين بقيمة متغير البيئة "CONFIG_PATH". للراحة ، يمكن الرجوع إلى الخلف في حالة عدم وجود متغير في مسار افتراضي معين ، والذي يجب الإشارة إليه في وثائق الوحدة. في هذه الحالة ، يجب أن يكون المسار المحدد مرتبطًا بجذر دليل التطبيق.
أمثلة التكوين
افترض أن لدينا خدمة تحتاج إلى تخزين الإعدادات للاتصال بـ Postgres ، وكذلك بعض المعلومات عن أنفسنا
تحتاج أولاً إلى تعريف تهيئة STAGE = الإعدادات الافتراضية. في ذلك سنصف الهيكل العام ، وكذلك جعل البيانات مستقلة عن المرحلة.
الإعدادات الافتراضية
# configuration/defaults/service.yaml defaults: version: 1.0.0 name: "config-example" # configuration/defaults/redis.yaml defaults: redis: host: "host" db: 0 port: 6379 password: "password"
ديف
# configuration/dev/redis.yaml dev: redis: host: "localhost" password: "hard_pwd"
الناتجة التكوين
version: 1.0.0 name: "config-example" redis: host: "localhost" db: 0 port: 6379 password: "hard_pwd"
الاستنتاجات
بهذه الطريقة الماكرة ، قمنا بحل مشكلة تكوين الخدمات في حديقة الحيوان الخاصة بنا ووضعنا كل شيء في وجهة نظر مشتركة. هذا المثال هو مجرد نقطة انطلاق ويمكن تعديله حسب تفاصيل مشروعك.
بالنسبة لأولئك المهتمين بطريقة التكوين هذه في "نموذج مكشوف":
حزمنا للغات البرمجة المختلفة للمساعدة في الكتابة تصبح شكر خاص
لروكي ،
SMGladkovskiy