Get a quote

الانتقال من PHP إلى Go في بيئة الإنتاج: دروس من عملية إعادة كتابة حقيقية

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

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

هذا التقدير بستة أشهر خاطئ تقريباً في كل مرة. ليس لأن Go صعبة، بل لأن مشروع PHP يحتوي على سنوات من العقود الضمنية التي لم يكتبها أحد. هذا ما رأيناه في عمليات ترحيل فعلية من PHP إلى Go لأنظمة خلفية تخدم شركات في لبنان ومنطقة MENA.

لماذا تقرر الفرق الانتقال من PHP إلى Go

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

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

الفريق يوظف مهندسين يعرفون Go ويريدون العمل بها. الاحتفاظ بالمواهب ضغط حقيقي في التوظيف التقني اللبناني والإقليمي.

مشكلة أداء محددة، عادةً حول نقطة نهاية عالية الحركة أو خط معالجة خلفي، أقنعت القيادة بأن نموذج التزامن في Go هو الحل.

نمط Strangler Fig: لماذا هو النهج الصحيح للترحيل

إعادة كتابة كاملة من PHP إلى Go هي من أعلى قرارات الهندسة المخاطرة. البديل هو نمط Strangler Fig: استبدال أجزاء من تطبيق PHP بخدمات Go تدريجياً بينما يعمل كلا النظامين في الإنتاج في وقت واحد.

تقنياً، البروكسي العكسي أو بوابة API تجلس أمام نظام PHP وخدمات Go. مسار بعد مسار، نقطة نهاية بعد نقطة نهاية، يُعاد تهيئة البروكسي لإرسال حركة المرور إلى خدمة Go بدلاً من معالج PHP. يتقلص تطبيق PHP بينما ينمو Go.

هذا النهج له تكاليف حقيقية. تشغيل نظامين في وقت واحد معقد تشغيلياً. لكن تلك التكاليف قابلة للإدارة والتنبؤ. تكاليف إعادة الكتابة الكاملة الفاشلة ليست كذلك.

الدرس الأول: قاعدة البيانات هي المشروع الضخم الحقيقي

كل فريق يبدأ ترحيل PHP إلى Go مؤمناً بأن قاعدة البيانات مجرد تفصيل سيقضي أسابيع في تصحيح هذا الاعتقاد. تطبيق PHP وقاعدة بياناته تطورا معاً. المخطط يعكس طريقة تفكير PHP.

الطوابع الزمنية غالباً مخزنة كأعداد صحيحة من time() في PHP أو كنصوص مُنسَّقة. الأعمدة النصية تحتوي على هياكل بيانات PHP المُسلسَلة. القيم الفارغة موجودة لأن الكتابة الفضفاضة في PHP تجعل تجاهل القابلية للفراغ سهلاً.

جانب Go لا يمكنه ببساطة الاتصال بنفس قاعدة البيانات والبدء في الاستعلام. سيصطدم فوراً بأعمدة قيمها صحيحة من الناحية التقنية لكن تفسيرها كُتب بطريقة PHP.

الدرس العملي: عامل ترحيل قاعدة البيانات كمسار عمل من الدرجة الأولى، لا كفكرة لاحقة. قبل أن تتمكن أي خدمة Go من استبدال نقطة نهاية PHP بشكل موثوق، يحتاج المخطط إلى مراجعة شاملة.

الطوابع الزمنية والمناطق الزمنية في PHP

معالجة التاريخ والوقت في PHP مصدر موثوق لأخطاء الترحيل. دالة date() في PHP تستخدم المنطقة الزمنية للخادم ما لم تُحدَّد صراحةً. كثير من تطبيقات PHP لا تعيّن date_default_timezone_set() وتعتمد على إعداد الخادم الافتراضي.

حزمة time في Go تعمل بـ UTC افتراضياً وتتعامل مع المنطقة الزمنية بشكل صريح. عندما تبدأ خدمة Go في قراءة الطوابع الزمنية التي كتبها تطبيق PHP، ستصادف كثيراً من الطوابع الصحيحة تقنياً لكن تفسير منطقتها الزمنية خاطئ.

راجع تخزين الطوابع الزمنية قبل بدء الترحيل. ضع قاعدة: كل الطوابع الزمنية المستقبلية مخزنة بتوقيت UTC في قاعدة البيانات. اكتب ترحيلاً يحول الطوابع الموجودة. طبّق UTC في Go في كل مكان.

توقعات الأداء: ما يتحسن فعلاً وما لا يتحسن

Go أسرع بالفعل من PHP للأعمال الكثيفة بمعالجة المعالج وتعامل الطلبات المتزامنة. تحسن الأداء في الترحيل الإنتاجي حقيقي لكنه أضيق مما يتوقع معظم الفرق.

لمعالجة الطلبات الخالصة تحت الحمل المتزامن، تُظهر خدمات Go تحسناً 3x إلى 10x في الطلبات في الثانية مقارنة بكود PHP المكافئ. بالنسبة لنقاط النهاية الثقيلة على قاعدة البيانات حيث 80% من وقت الطلب هو تنفيذ استعلام PostgreSQL، التحسن أقرب إلى 10% إلى 30%.

للوظائف الخلفية التي كانت تُجدوَل سابقاً عبر عمليات cron في PHP، يسمح نموذج goroutine في Go عادةً بتنفيذ متزامن 5x إلى 20x أكثر على نفس الأجهزة.

الدروس الرئيسية من بيئة الإنتاج

قاعدة البيانات هي التحدي الحقيقي للترحيل. راجعها قبل كتابة أي كود Go.

الجلسات والمصادقة تتطلب بنية جسر صريحة خلال فترة الانتقال.

المناطق الزمنية في PHP غالباً ضمنية. اجعلها صريحة قبل الترحيل.

تحسينات الأداء حقيقية لكنها مركّزة في حالات استخدام محددة. قِس أولاً ثم قرر.

nمقاربة Strangler Fig ليست اختيارية للأنظمة الإنتاجية ذات المستخدمين الحقيقيين.

العودة إلى المدونة
Chat on WhatsApp