عرضت عليّ ذات مرة شركةٌ ناشئة في جولة تمويل من الفئة B مخطّط بنيتها التقنية بفخرٍ واضح: ثلاث وأربعون خدمةً مصغّرة، و«service mesh»، ونواقل أحداث، وكل ما قد يخطر ببالك. فسألتهم: كم يستغرق لديكم إطلاق تعديلٍ على مسار الدفع؟ فساد الصمت. كان الجواب أحد عشر يوماً — لأن تغيير سطرٍ واحد في السعر يمسّ ست خدمات تملكها أربعة فرق، ولا بدّ لأحدهم أن ينسّق عمليات النشر.
لم تكن لديهم بنية خدمات مصغّرة، بل نظام أحادي موزّع (distributed monolith) مثقلٌ باستدعاءات شبكية إضافية، وكان أبطأ في التغيير من القاعدة البرمجية التي هربوا منها.
الألم الذي تحاول حلّه تنظيميٌّ لا تقني
الخدمات المصغّرة، في جوهرها، حلٌّ لمشكلةٍ بشرية. فحين يكون لديك مهندسون كُثر يتعثّر بعضهم ببعض داخل قاعدة برمجية واحدة — تعارضات دمج، وعمليات نشر متشابكة، وقطار إصداراتٍ لا يقدر أحد على إبطائه — يتيح تقسيم النظام لكل فريق أن يمتلك جزأه ويُطلقه باستقلال. هذا هو المكسب. أما كل ما سواه (التوسّع، والصمود، وحرية تعدّد لغات البرمجة) فغالباً ثانوي، وكثيراً ما يمكن تحقيقه داخل نظام أحادي جيّد البنية.
لذا فإن السؤال الأول الصادق ليس «كيف نُفكّك مجالنا؟»، بل «هل بنيتنا الحالية تؤلمنا فعلاً، وأين؟». إن كان لديك ثمانية مهندسين وخط نشرٍ واحد، فإن الخدمات المصغّرة ستُحمّلك ضريبة الأنظمة الموزّعة — أعطال الشبكة، والاتساق النهائي، والتتبّع الموزّع، وأنماط الـ«saga» لما كان يوماً معاملة قاعدة بيانات واحدة — دون أن تمنحك من الفائدة ما يُذكر.
إن عجزت عن رسم حدٍّ نظيف بين وحدات نظامك الأحادي، فلن يرسمه لك توزيعُ النظام عبر الشبكة؛ كل ما سيفعله أنه يُصعّب رؤية الفوضى.
إشاراتٌ تدل أن الألم حقيقي
في مشاريعي، أبحث عن ألمٍ ملموسٍ قابلٍ للقياس قبل أن أوصي بأي تقسيم. ومن الإشارات التي تهمّ:
- تشابك النشر. ميزاتٌ مستقلة لا يمكن إطلاقها باستقلال لأنها تتشارك إصداراً واحداً، فتصطفّ الفرق في طابورٍ خلف بعضها.
- احتياجات توسّعٍ متباينة. مكوّنٌ واحد — ترميز الفيديو، أو توليد التقارير، أو فهرس البحث — يحتاج موارد تفوق البقية عشرين ضعفاً، وأنت تدفع ثمن توسيع التطبيق كله لتلبية حاجته وحده.
- نطاق الانفجار. تسرّب ذاكرةٍ في ميزةٍ إدارية نادرة الاستخدام يُسقط مسار الدفع، لأن كل شيء يعمل في عملية (process) واحدة.
- طوبولوجيا الفرق. لديك خمسة فرق وقاعدة برمجية واحدة، وقد صارت كلفة التنسيق ظاهرةً على خارطة الطريق.
ولاحظ ما ليس في القائمة: «قرأنا أن نتفليكس تفعل ذلك»، أو «الأمر يبدو أكثر عصرية». هذه ليست إشارات، بل موضة.
ابدأ بالعمل المملّ: الأحادي المُقسَّم إلى وحدات
قبل أن تمسّ الشبكة، استحقّ الحدود داخل تطبيقك القائم. فالأحادي المُقسَّم إلى وحدات (modular monolith) — وحدات واضحة بواجهات صريحة، بلا وصولٍ مباشر إلى جداول وحدةٍ أخرى، واعتمادياتٌ تشير في اتجاه واحد — يمنحك 80% من الوضوح المعماري بـ5% من الكلفة التشغيلية. تظل تنشر منتَجاً واحداً، وتظل تحصل على معاملة قاعدة بيانات واحدة، لكن الحدود صارت حقيقية.
هذه أعلى الخطوات مردوداً، ومع ذلك تتخطاها معظم الفرق. فإن استطاع فريقك الحفاظ على تلك الحدود الداخلية ستة أشهر دون غشّ، صار الاستخراج لاحقاً شبه آليّ. وإن عجز عن حفظ الحدّ داخل العملية الواحدة، فلن يحفظه عبر الشبكة قطعاً — بل سيضيف زمن استجابةٍ وإعادات محاولة إلى الفوضى نفسها.
وحين تستخرج، فافعلها حدّاً واحداً في كل مرة
اختر الوحدة ذات الحدّ الأوضح والسبب المستقل الأقوى للانتقال — غالباً تلك ذات التوسّع المتباين أو الفريق المختلف. استخرجها وحدها، وشغّلها في الإنتاج، واستشعر ثقلها التشغيلي: المناوبة، والرصد، وخط النشر، وإدارة إصدارات العقود (contract versioning). ثم قرّر إن كانت التالية تستحق. وتكتشف معظم الشركات أن ثلاث أو أربع خدماتٍ مختارةٍ بعناية تلتقط كل الفائدة تقريباً، وأن الثلاثين الباقية ليست إلا ألماً.
الكلفة التي لا يضعها أحد على الشريحة
الخدمة المصغّرة ليست مجانية يوم تُنشئها؛ إنها التزامٌ دائم: لها خط CI/CD خاص، ولوحات ومنبّهات خاصة، وأسرار وترقيات اعتماديات خاصة، وموضعها الخاص في دورة المناوبة. اضرب ذلك في أربعين، تكن قد بنيت وظيفة ثانية بدوامٍ كامل لا علاقة لها بمنتجك.
والكلفة الصامتة الأخرى هي التنقيح (debugging). ففي النظام الأحادي، يروي أثر المكدّس (stack trace) القصة كاملة. أما عبر الخدمات، فيتشعّب فعل مستخدمٍ واحد عبر عشر قفزات، فتجد نفسك تخيط معرّفات الترابط (correlation IDs) عبر السجلّات في الثانية صباحاً للإجابة عن سؤالٍ كانت نقطة توقّفٍ واحدة كفيلةً بالإجابة عنه سابقاً. خصّص ميزانية لهذا الواقع، أو لا تلتزم به أصلاً.
من أين تبدأ يوم الاثنين
لا تجدول هجرة، بل جدول تدقيقاً صادقاً. دوّن الألم الفعلي — أزمنة النشر، ونطاق انفجار الحوادث، والميزات العالقة في طابور تنسيق — وضع الأرقام إلى جانب كل بند. فإن جاءت القائمة هزيلة، فجوابك نظام أحادي مُقسَّم إلى وحدات وانضباطٌ أفضل في الحدود، لا نظام موزّع.
وإن كان الألم حقيقياً ومحصوراً، فاستخرج خدمة واحدة بالضبط، تلك التي تشير إليها الأدلة، وعِش معها قبل استخراج الثانية. دع البنية تتبع الألم، لا محاضرة المؤتمر.
الخدمات المصغّرة أداةٌ لنوعٍ محدّد من الألم. وقبل أن تمدّ يدك إليها، تأكّد أنك تستطيع تسمية موضع الألم — وأن حلاًّ أبسط لن يشفيه بالقدر نفسه.