ما الذي علّمنا إياه تشغيل بوت على أكثر من 2000 سيرفر Discord
أربعة أشياء تعمل على نطاق واسع بشكل مختلف عما تفترضه أثناء كتابة الكود.

بوت Discord على ثلاثة سيرفرات والبوت نفسه على أكثر من ألفي سيرفر ليسا البرنامج نفسه بحجم أكبر. حفنة من الافتراضات التي لا ضرر منها إطلاقًا على نطاق صغير تصبح، بعد حجم معين، بالضبط الأخطاء الأصعب في العثور عليها.
إليك أربعة منها كلّفتنا أعطالًا حقيقية.
1. الأعطال لا تنتشر بالتساوي، بل تختبئ
يعمل AlphaCloud موزعًا على عدة عمليات تُسمى Shards. يقرر Discord أي سيرفر يقع على أي Shard، ولا يعرف كل Shard إلا سيرفراته الخاصة.
وهذا ينتج نوعًا من الأعطال يبدو من الخارج كأنه عشوائية: رسائل الترحيب تعمل على بعض السيرفرات ولا تعمل على أخرى. لا خطأ في السجل، ولا تنبيه، ولا شيء. السبب كان استدعاءً شبكيًا واحدًا دون مهلة زمنية. إذا قبل الطرف الآخر الاتصال ثم صمت، ينتظر الكود طوال ما تبقى من عمر العملية. وكل ما بعده لا يحدث أبدًا، ولأنه لا يُطلق أي خطأ، فلا شيء يبلّغ عن خطأ.
الدرس غير مثير وشامل: كل استدعاء صادر يحتاج إلى حد أعلى. الاستدعاء الذي ينتظر إلى الأبد أسوأ من الاستدعاء الذي يفشل، لأن الفشل على الأقل مرئي.
2. إعادة التشغيل ليست إصلاحًا، بل موعد نهائي
بينما لم نكن نعرف السبب، كانت إعادة تشغيل الـ Shard المتأثر تساعد بشكل موثوق. وهذه بالضبط مشكلة إعادة التشغيل: إنها تنجح، وهذا يزيل الضغط للبحث عن السبب.
نتعامل الآن مع سؤال «هل تساعد إعادة التشغيل؟» كتشخيص، لا كعلاج. إذا كانت تساعد، فالحالة المعطوبة تعيش في الذاكرة، وهناك موضع في الكود يبنيها ولا يهدمها أبدًا.
والعكس صحيح أيضًا: كل ما يجب أن ينجو من إعادة التشغيل مكانه قاعدة البيانات. إذا كانت عملية متعددة الخطوات جارية، لنقل تغيير رتبة لآلاف الأعضاء، وتوقفت العملية في منتصفها، فلا يجوز أن تختفي العملية ببساطة. يجب اكتشافها ومتابعتها عند التشغيل التالي.
3. حدود Discord تسري على البوت، لا على العملية
يحدد Discord عدد الطلبات التي يمكن لبوت إرسالها في الثانية. الافتراض البديهي: عمليات أكثر، إنتاجية أكبر. خطأ. الحد مفروض على البوت لا على العملية. ثلاثة Shards لكل منها ميزانية كاملة تساوي ثلاثة أضعاف المسموح، فيقيّد Discord حينها الثلاثة جميعًا.
لذلك تحسب كل عملية من عملياتنا عدد العمليات الموجودة إجمالًا، ولا تأخذ إلا حصتها. يبدو هذا بديهيًا، لكنه لم يكن كذلك، وبقي الخطأ غير مرئي لوقت طويل لأن كل عملية بمفردها كانت تبدو منضبطة تمامًا.
فخ مشابه: المهام المتكررة تعمل على فترات ثابتة، لنقل كل خمس دقائق. إذا بدأت كل الـ Shards في الوقت نفسه، فإنها تطلق مهامها في اللحظة نفسها إلى الأبد. ومنذ ذلك الحين تحصل كل عملية على إزاحة عشوائية عند بدء التشغيل.
4. ما يضبطه الناس فعلًا ليس ما تتوقعه
الجانب التقني نصف القصة. النصف الآخر: بالنسبة لمعظم السيرفرات، الإعداد الافتراضي هو الإعداد. الوحدة التي تكون قيمها الافتراضية خاطئة تكون مضبوطة بشكل خاطئ على الغالبية العظمى من السيرفرات، مهما كانت صفحة الإعدادات جيدة.
وينتج عن ذلك أمران بالنسبة لنا. أولًا، كل قيمة افتراضية تتطلب تفكيرًا أكثر من الإعداد نفسه. ثانيًا، السؤال الأفضل لوحدة جديدة ليس «ما الذي يمكن ضبطه هنا»، بل «ماذا تفعل هذه الوحدة حين لا يضبط أحد أي شيء، وهل هذا صحيح لسيرفر عادي».
وهذا أيضًا سبب قرار يبدو للوهلة الأولى عكس ذلك: منذ v1.8.0 يمكن تصميم كل رسالة تقريبًا يرسلها البوت بحرية. لكن الكتل الإلزامية مثل السبب في رسالة التحذير الخاصة أو قائمة الفئات في لوحة التذاكر يمكن نقلها ولا يمكن حذفها. حرية التصميم، نعم، لكن ليس إلى حد أن يبني السيرفر عن غير قصد شيئًا يبدو أنه يعمل وهو لا يعمل.
الخيط المشترك
ثلاثة من الأربعة هي الفكرة نفسها بأزياء مختلفة: عند هذا الحجم، العطل الصامت أغلى من العطل الصاخب. الانهيار يُبلَّغ عنه ويُصلح. أما الميزة التي تتوقف ببساطة عن فعل أي شيء، فقد تبقى كذلك لأشهر، وتكتشف الأمر عبر بلاغ عن خطأ من شخص تكلّف عناء الكتابة.
لذلك السؤال الذي نطرحه الآن أولًا عن أي كود جديد ليس «هل يعمل هذا»، بل «كيف يبدو حين لا يعمل، وهل سنلاحظ ذلك».
مقالات أخرى
مراقبة 4000 سيرفر Discord: Grafana وPostHog وما أظهراه لنا
حلقة تسببت بصمت في نصف حركة البيانات لدينا، وثلاثة ملايين طلب عديم الفائدة يوميًا، وهجوم انتهى بعد دقيقة واحدة. ما الذي تراه مراقبتنا، وما الذي لا تراه عمدًا.
خلف الكواليسعندما أحال مزوّد الذكاء الاصطناعي لدينا النموذج إلى التقاعد
تبديل نموذج، وردود فارغة دون أي خطأ، وفاتورة ارتفعت فجأة أضعافًا. ما الذي تعطّل، ولماذا كان السبب صعب الرؤية إلى هذا الحد.
خلف الكواليسالقانون داخل الكود الخاص بنا
زر إلغاء يجب أن يعمل دون تسجيل دخول. ونموذج يجب ألا يرفضك أبدًا. لماذا تُعد الالتزامات القانونية عندنا بنية تقنية، لا مجرد نصوص جاهزة.