تحديث المونوليث كجراحة قلب مفتوح: كيف أنقذنا نمط الخانق (Strangler Fig) من جحيم “إياك أن تلمس هذا الكود”؟

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

“إياك أن تلمس هذا الكود… لا نعرف ماذا سيحدث.”

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

ما هو الجحيم الذي كنا نعيش فيه؟ (عالم المونوليث)

قبل أن نغوص في الحل، دعونا نفهم طبيعة الوحش الذي كنا نتعامل معه. النظام المتراص أو “المونوليث” (Monolith) هو تطبيق برمجي تكون فيه جميع المكونات (واجهة المستخدم، منطق العمل، الوصول للبيانات) مترابطة ومتشابكة في قاعدة كود واحدة ضخمة.

في البداية، يكون المونوليث رائعاً. يسهل تطويره ونشره. لكن مع مرور السنين وتزايد الميزات، يتحول إلى ما نسميه “كرة الطين الكبيرة” (Big Ball of Mud). تصبح المشاكل كالتالي:

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

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

شجرة التين الخانقة: المنقذ الذي لم نتوقعه

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

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

خطوات عملية لتطبيق نمط الخانق

النظرية جميلة، لكن كيف نطبقها عملياً؟ إليك الخطوات التي اتبعناها، والتي يمكنك اتباعها في مشاريعك:

الخطوة الأولى: تحديد “الشق” الأول (Identify the First Seam)

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

الخطوة الثانية: بناء “الواجهة” أو الوكيل (The Facade/Proxy)

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

يمكن أن يكون هذا الوكيل بسيطاً مثل إعدادات في خادم ويب مثل Nginx أو Apache، أو يمكن أن يكون بوابة واجهات برمجية (API Gateway) متكاملة مثل Kong أو Tyk أو حتى خدمة مخصصة بنيتها بنفسك.

مثال بسيط باستخدام Nginx:

لنفترض أن نظامك القديم يعمل على http://legacy-monolith:8080. إعدادات Nginx الأولية ستكون مجرد تمرير لكل شيء:


server {
    listen 80;
    server_name yourapp.com;

    location / {
        proxy_pass http://legacy-monolith:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

الآن، كل حركة المرور تمر عبر Nginx. المستخدم لا يشعر بأي فرق، لكنك الآن تملك مفتاح التحكم.

الخطوة الثالثة: بناء الخدمة الجديدة (Implement the New Service)

الآن يأتي الجزء الممتع. قم ببناء الخدمة الجديدة (Microservice) التي ستحل محل الوحدة التي اخترتها. استخدم أحدث التقنيات التي تريدها! (Node.js, Go, Python, Rust.. ما يحلو لك). في حالتنا، بنينا خدمة التقارير الجديدة باستخدام Python و FastAPI لأنها سريعة وممتازة للتعامل مع البيانات.

لنفترض أن الخدمة الجديدة تعمل على http://reports-service:3000.

الخطوة الرابعة: البدء بالخنق (Redirect and Strangle)

الآن، نعود إلى الوكيل (Nginx) ونبدأ بتوجيه الطلبات. سنقوم بتوجيه الطلبات الخاصة بالتقارير فقط إلى الخدمة الجديدة، بينما تبقى بقية الطلبات تذهب إلى المونوليث القديم.


server {
    listen 80;
    server_name yourapp.com;

    #-- الخنق يبدأ هنا! --#
    # أي طلب يبدأ بـ /api/reports يذهب للخدمة الجديدة
    location /api/reports {
        proxy_pass http://reports-service:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    #-- كل شيء آخر يذهب للنظام القديم كالمعتاد --#
    location / {
        proxy_pass http://legacy-monolith:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

بهذه الطريقة، أنت “خنقت” جزءاً من المونوليث. يمكن للمستخدمين الآن الوصول إلى التقارير الجديدة والحديثة، بينما لا يزالون يستخدمون بقية النظام القديم. يمكنك فعل ذلك تدريجياً، مثلاً توجيه 10% من المستخدمين أولاً، ثم 50%، وهكذا.

الخطوة الخامسة: التكرار ثم إزالة القديم (Rinse, Repeat, and Retire)

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

نصائح أبو عمر من أرض المعركة

من خلال تجربتنا هذه، تعلمت بعض الدروس التي أود مشاركتها معكم:

  • ابدأ صغيراً جداً: لا تختر أكبر وأعقد جزء من النظام لتبدأ به. اختر شيئاً بسيطاً ليكون “فوزاً سريعاً” (Quick Win) يرفع معنويات الفريق ويعطي ثقة للإدارة.
  • المراقبة والتوثيق هما مفتاح النجاة: استثمر بقوة في أدوات المراقبة (Monitoring) والتتبع (Tracing). يجب أن تعرف فوراً إذا كانت خدمتك الجديدة تواجه مشاكل. وثّق كل خطوة وكل قرار.
  • تعامل مع البيانات بحذر: أصعب جزء في هذه العملية هو التعامل مع قاعدة البيانات المشتركة. فكر جيداً في استراتيجية نقل البيانات. هل ستنسخ البيانات؟ هل ستستخدم الخدمة الجديدة نفس قاعدة البيانات مؤقتاً؟ لكل حالة حلها.
  • كن مستعداً للتراجع: جمال طبقة الوكيل هو أنها تسمح لك بالتراجع بسرعة. إذا فشلت الخدمة الجديدة، يمكنك بتعديل سطر واحد في إعدادات Nginx إعادة توجيه كل شيء إلى النظام القديم مرة أخرى.

الخلاصة: لا تهدم البيت القديم، بل ابن حوله قصراً جديداً 🌿

كان تحديث المونوليث القديم كابوساً، وكانت فكرة إعادة كتابته من الصفر مرعبة أكثر. نمط الخانق (Strangler Fig) لم يكن مجرد حل تقني، بل كان تغييراً في العقلية. لقد علمنا أن التغيير لا يجب أن يكون ثورياً ومدمراً، بل يمكن أن يكون تدريجياً ومنظماً وآمناً.

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

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

نصائح برمجية

كانت أرقامي السحرية طلاسم لا تُقرأ: كيف أنقذتنا ‘الثوابت المسماة’ من جحيم ‘ماذا يعني هذا الرقم؟’

في عالم البرمجة، الأرقام العشوائية في الكود أو "الأرقام السحرية" هي وصفة لكارثة مستقبلية. في هذه المقالة، أشارككم قصة من واقع تجربتي وكيف أن استخدام...

25 مايو، 2026 قراءة المزيد
تسويق رقمي

ما وراء الكلمات المفتاحية: كيف حولنا بيانات Schema.org إلى أسلحة سرية في حرب نتائج البحث؟

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

25 مايو، 2026 قراءة المزيد
صورة المقال
تجربة المستخدم والابداع البصري

كانت شاشاتنا الفارغة مقبرة للتفاعل: كيف أنقذتنا ‘الحالات الفارغة الذكية’ من جحيم ‘وماذا الآن؟’

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

25 مايو، 2026 قراءة المزيد
برمجة وقواعد بيانات

كانت استعلاماتنا تزحف: كيف أنقذتنا فهارس قواعد البيانات من جحيم البحث البطيء؟

قصة من الميدان عن كيفية تحويل استعلامات SQL البطيئة التي تشبه السلحفاة إلى عمليات فائقة السرعة باستخدام أداة بسيطة وقوية: فهارس قواعد البيانات. مقالة عملية...

25 مايو، 2026 قراءة المزيد
الشبكات والـ APIs

من جحيم الـ Polling إلى نعيم الـ Webhooks: كيف أنقذت “خطافات الويب” تطبيقاتنا من السؤال المستمر “هل من جديد؟”

أروي لكم قصة من واقع تجربتي كمبرمج، كيف انتقلنا من طريقة الاستطلاع المستمر (Polling) المرهقة للخوادم، إلى الاعتماد على "خطافات الويب" (Webhooks) الذكية. مقالة عملية...

25 مايو، 2026 قراءة المزيد
البودكاست