التطوير القائم على الجذع وأعلام الميزات
التطوير القائم على الجذع وأعلام الميزات
قارن الدرس السابق بين استراتيجيات التفريع جنبًا إلى جنب. يتعمق هذا الدرس في إحداها — التطوير القائم على الجذع (TBD) — ويقرنها بالتقنية التي تجعلها آمنة على نطاق واسع: أعلام الميزات. هذان الأسلوبان معًا هما الطريقة التي تطرح بها شركات Google وMeta وNetflix عشرات التغييرات على الإنتاج كل يوم دون أي فروع ميزات تعيش لأسابيع.
ما معنى التطوير القائم على الجذع فعلًا
في TBD، يدمج كل مهندس الكود في فرع مشترك واحد — يُسمى عادةً main أو trunk — مرة على الأقل يوميًا. لا توجد فروع ميزات طويلة الأمد. الفرع، إن وُجد أصلًا، يعيش لساعات لا لأيام. وفور اكتماله (حتى جزئيًا) يُدمج في الجذع.
يبدو هذا متهورًا. الواقع أنه العكس تمامًا. يفرض انضباط الدمج المتكرر ثلاثة أمور:
- تظهر التعارضات فورًا. عندما تنتظر أسبوعين للدمج، تواجه تعارضًا بآلاف الأسطر. عندما تدمج يوميًا، تكون التعارضات بسيطة.
- تعمل CI على كود متكامل حقيقي. مجموعة اختبار تعمل على فرعك فقط لا تكتشف أخطاء التكامل.
- يشترك الفريق في حقيقة واحدة. لا يوجد "سندمج بعد الإصدار". الجميع ينظر دائمًا إلى نفس قاعدة الكود.
الفروع قصيرة الأمد: الاستثناء المسموح به
يسمح TBD الصافي بصفر فروع — كل commit يذهب مباشرةً إلى main. عمليًا، تستخدم معظم الفرق متغيرًا معتدلًا: فروع ميزات قصيرة الأمد لا تعيش أكثر من يوم أو يومين وتمر عبر pull request قبل الدمج. يُسمى هذا أحيانًا "TBD على نطاق واسع".
القواعد التي تجعل الفروع قصيرة الأمد آمنة:
- انشئ الفرع دائمًا من أحدث commit في
main— أبدًا من فرع آخر. - ادمج (أو أعد التأسيس) من
mainإلى فرعك مرة يوميًا على الأقل إن عاش الفرع أكثر من 24 ساعة. - احرص على أن يكون الـ PR صغيرًا بما يكفي للمراجعة في أقل من 30 دقيقة. إن كانت الميزة كبيرة جدًا، قسّمها إلى شرائح قابلة للدمج بشكل مستقل — كل منها خلف علم ميزة.
- احذف الفرع فورًا بعد الدمج. لا فروع معلقة على origin.
المشكلة الجوهرية التي يكشفها TBD
إن لم يكن بإمكانك امتلاك فروع طويلة الأمد، كيف تطرح ميزة تستغرق أسبوعين للبناء؟ لا يمكنك إخفاؤها في فرع. لا يمكنك رفض الدمج حتى تنتهي. الجواب هو: تدمج باستمرار، لكنك تتحكم في وقت تشغيل الكود. هذه هي مهمة أعلام الميزات.
أعلام الميزات: فصل النشر عن الإصدار
علم الميزة (يُسمى أيضًا feature toggle أو feature gate) هو شرط في الكود يقرر في وقت التشغيل ما إذا كانت الميزة نشطة. يُنشر الكود إلى الإنتاج باستمرار؛ العلم يتحكم في من يراها ومتى.
هذا هو النموذج الذهني الأساسي: النشر حدث تقني (الكود يصل إلى الخوادم)؛ الإصدار حدث تجاري (المستخدمون يرون الميزة). يفصل TBD + الأعلام بينهما تمامًا. يمكنك النشر 50 مرة يوميًا بينما تطرح ميزة لـ 1% من المستخدمين يوم الثلاثاء الساعة العاشرة صباحًا عندما يكون فريق الدعم مستعدًا.
أنواع الأعلام التي تحتاج معرفتها
ليست جميع الأعلام متشابهة. استخدام النوع الخاطئ في السياق الخاطئ يُسبب ديون تقنية ومخاطر تشغيلية:
- أعلام الإصدار — قصيرة الأمد؛ تخفي الميزات الجارية. احذفها فور اكتمال الطرح. هذه هي العمود الفقري لـ TBD.
- أعلام التجربة (A/B) — توجه المستخدمين إلى نسخة A أو B؛ مقاسة بالتحليلات. تعيش طوال التجربة ثم تُحذف.
- أعلام العمليات — قواطع دائرة ومفاتيح إيقاف. "عطّل محرك التوصيات إذا كانت خدمة ML محملة زيادة." طويلة الأمد وتُعامل كبنود في كتب التشغيل.
- أعلام الصلاحيات — تقييد الميزات حسب شريحة المستخدم أو الجغرافيا أو الخطة. قد تكون منطق تجاري دائم.
تطبيق الأعلام: من البسيط إلى مستوى الإنتاج
في أبسط مستوياتها، العلم مجرد فحص متغير بيئة. هذا يصلح لأعلام العمليات والإصدارات المبكرة:
للاستهداف على مستوى المستخدم — النوع المطلوب لاختبارات A/B أو الطرح التدريجي — تحتاج خدمة تقييم أعلام. الخيار المفتوح المصدر القياسي في الصناعة هو OpenFeature (مشروع CNCF) مقرونًا بخلفية مثل Flagd أو خدمة مُستضافة مثل LaunchDarkly. إليك إعداد flagd واقعي:
يُقدّم هذا الإعداد واجهة الدفع الجديدة لمستخدمَين تجريبيَّين محددَين، ولـ 10% عشوائية من الجميع — مع ثبات التقسيم العشوائي (يحصل نفس المستخدم دائمًا على نفس النسخة لأن مفتاح الهاش يتضمن اسم العلم). يُعاد تحميل الملف تلقائيًا؛ لا حاجة لإعادة التشغيل لتغيير نسبة الطرح.
نمط Strangler Fig مع الأعلام
إعادة الهيكلة الكبيرة — استبدال معالج دفع، إعادة كتابة خدمة مصادقة — تتم بأمان مع نمط Strangler Fig: شغّل مسارَي الكود القديم والجديد بالتوازي، وجّه نسبة متزايدة من الحركة إلى المسار الجديد عبر علم، واستبعد المسار القديم فقط عندما يعالج الجديد 100% من الحركة لفترة مستدامة. العلم هو رافعة التراجع في كل خطوة.
أنماط الفشل الشائعة في الإنتاج
يفشل TBD والأعلام بطرق يمكن التنبؤ بها. معرفتها يتيح لك تجنبها:
- الـ commit مباشرةً على الجذع دون اجتياز CI. يتطلب TBD خط CI سريعًا وموثوقًا كجهاز مناعي. إن كان CI غير موثوق أو بطيئًا (أكثر من 10 دقائق)، سيتجاوزه المهندسون. استثمر في سرعة الاختبار أولًا.
- الأعلام في الطبقة الخاطئة. علم يُقيَّم في ثلاث خدمات مختلفة بنتائج غير متسقة أسوأ من لا علم. قيّم الأعلام مرة واحدة (من جانب الخادم، في API gateway أو SDK مشترك) وأرسل النتيجة إلى المراحل التالية.
- لا رصد لحالة الأعلام. عند وقوع حادثة، تحتاج معرفة أي الأعلام كانت نشطة للمستخدمين المتضررين فورًا. أرسل نتيجة تقييم العلم كحقل سجل هيكلي أو سمة trace على كل طلب.
- تضخم الأعلام. 500 علم نشط في قاعدة كود دون سجلات ملكية. عيّن مالكًا وتاريخ انتهاء لكل علم عند الإنشاء. أتمتة التذكيرات.
الصورة الكاملة: يوم في حياة المهندس
مهندس أول في فريق TBD يعمل على ميزة دفع جديدة يفعل ما يلي: ينشئ فرعًا من main، يكتب شريحة أولى نحيفة (ترحيل قاعدة البيانات والمسار خلف العلم)، يفتح PR في نفس اليوم، يُدمج. العلم مُغلق. في اليوم التالي: ينشئ فرعًا جديدًا من أحدث main، يضيف طبقة الواجهة خلف نفس العلم، يُدمج بنهاية اليوم. العلم لا يزال مُغلقًا. اليوم الثالث: منطق الخلفية مكتمل، مُدمج، اختبارات شاملة مضافة. العلم يُفعَّل لبيئة QA. اليوم الرابع: العلم يُفعَّل لـ 5% من حركة الإنتاج. المؤشرات تبدو جيدة. اليوم الخامس: 100%. اليوم السادس: PR لحذف العلم ومسار الكود القديم. يُدمج. تم. لم تعش الميزة في فرع أكثر من 24 ساعة، رغم أنها استغرقت خمسة أيام للبناء بأمان.
هذا هو الانضباط الذي يتيح للفرق النشر بلا خوف. الفرع قصير؛ المخاطرة تُدار بالعلم. هذه هي الفكرة بأكملها.