يا جماعة الخير، السلام عليكم ورحمة الله.
اسمحوا لي اليوم أحكي لكم قصة صارت معنا قبل كم سنة، قصة علّمتنا درس قاسي ما بننساه. كنا في نص الليل، يوم خميس، والمفروض الكل مروّح على بيته يستعد للويكند. فجأة، التلفونات بدأت ترن، ورسائل الـ Slack تضوي الشاشات: “الموقع واقع! المستخدمين مش قادرين يعملوا طلبات!”.
نزلنا كلنا على المكتب، اللي كان قريب واللي كان بعيد، وفتحنا الشاشات والقهوة صارت زي المي. المشكلة كانت غامضة، جزء معين في النظام كان ينهار تحت الضغط بطريقة غريبة. بعد ساعات من الحفر والبحث في الكود، واحد من الشباب الجداد سأل سؤال بريء بس كان زي السكينة في الجرح: “يا جماعة، ليش أصلاً مستخدمين هاي المكتبة (Library) بالذات لمعالجة الصور؟ سمعت إنها بتعمل مشاكل في الـ Memory.”
ساد صمت رهيب في الغرفة. الكل صار يطلع في بعضه. الجواب كان عند “محمود”، الشب اللي كان الـ Tech Lead تبعنا وسافر يكمل دراسته في ألمانيا قبل 6 شهور. بلّشنا نحفر في قنوات الـ Slack زي اللي بدور على إبرة في كومة قش. بعد ساعة، لقينا محادثة عمرها سنة ونص، محادثة مقطّعة بين محمود ومهندس ثاني ترك الشركة برضه. فيها كلام عن “سرعة” و”سهولة” بس ما في أي تفاصيل عن السياق، ليش اختاروها، وشو البدائل اللي فكروا فيها، وشو العيوب اللي كانوا عارفينها وقبلوا فيها.
في هذيك الليلة، واحنا بنعمل Hotfix سريع الساعة 4 الفجر، أقسمت إني ما رح أسمح لهذا الموقف يتكرر. قرار تقني مصيري، أثّر على كل شغلنا، كان تاريخه كله عبارة عن كم رسالة ضايعة في Slack. هون بلشت رحلتنا مع المنقذ: سجلات القرارات المعمارية (ADRs).
مقبرة القرارات: لماذا أدوات الدردشة ليست ذاكرة لفريقك
مشكلتنا ما كانت فريدة من نوعها. معظم الفرق التقنية اليوم بتستخدم أدوات زي Slack أو Microsoft Teams. هي أدوات عظيمة للتواصل اللحظي، بس كارثية كأداة للتوثيق أو كذاكرة طويلة الأمد للفريق. ليش؟
صعوبة البحث الكارثية
جرب ابحث عن قرار عمره سنة في Slack. حتى لو لقيت الرسالة، بتكون بدون سياق. مين كان في الاجتماع؟ شو النقاش اللي دار قبلها؟ شو الاعتراضات اللي انحكت؟ كل هذا بيضيع. البحث في Slack زي اللي بنادي في واد، الصدى ممكن يرجع بس المعلومة الكاملة مستحيل.
فقدان السياق هو القاتل الصامت
أخطر إشي مش إنك ما تعرف “شو” القرار، الأخطر إنك ما تعرف “ليش” تم اتخاذ القرار. المحادثات النصية بتعطيك القرار النهائي (“يلا نستخدم PostgreSQL”)، لكنها بتخفي 90% من الصورة: ليش مش MySQL؟ هل فكرنا في قواعد البيانات NoSQL؟ شو كانت أولوياتنا وقتها (سرعة التطوير، التكلفة، قابلية التوسع)؟ بدون هذا السياق، أي محاولة لتغيير القرار في المستقبل بتكون مبنية على تخمينات.
ذاكرة الفريق المؤقتة
الناس بتيجي وبتروح. لما مهندس خبير يترك الشركة، هو بياخذ معه جزء كبير من تاريخ المشروع في عقله. إذا كان هذا التاريخ مش مكتوب وموثق، فكأنك بتحذف جزء من الذاكرة الصلبة للمشروع. الوافد الجديد بصير يسأل أسئلة الكل نسي إجاباتها، والنتيجة هي إعادة اختراع العجلة، أو الأسوأ، تكرار نفس الأخطاء القديمة.
المنقذ الذي لم نتوقعه: تعرف على سجلات القرارات المعمارية (ADRs)
بعد ليلة الكارثة، بدأت أبحث عن حلول. قرأت عن مفهوم بسيط لكن عبقري اسمه “Architectural Decision Records” أو اختصارًا ADRs. الفكرة بسيطة لدرجة إنك بتستغرب كيف ما فكرت فيها من قبل.
ما هي الـ ADRs ببساطة؟
الـ ADR هو ملف نصي صغير (عادة بصيغة Markdown) بيوصف قرار معماري مهم تم اتخاذه، والسياق المحيط فيه. فكر فيه كأنه “محضر اجتماع” مركز ومختصر جدًا خاص بقرار واحد فقط. كل قرار مهم، بنعمله ملف ADR خاص فيه، وبنحفظه مع الكود في الـ Git repository، في مجلد مثلاً اسمه docs/adrs.
هاي الملفات بتصير هي “الذاكرة” الحقيقية للمشروع. أي حدا، جديد أو قديم، بده يعرف ليش استخدمنا تقنية معينة أو اتبعنا نمط تصميم معين، كل اللي عليه يعمله هو إنه يقرأ الـ ADRs المرتبة حسب التاريخ.
ما الذي يعتبر قرارًا معماريًا؟
مش كل قرار بنكتبله ADR طبعًا، وإلا بنقضي وقتنا كله في الكتابة. القرار المعماري هو قرار “مهم” و”صعب التغيير”. يعني قرار له تأثير واسع على النظام أو على طريقة عمل الفريق.
- مثال على قرار معماري يستحق ADR: اختيار لغة البرمجة الأساسية للمشروع، اختيار قاعدة البيانات، استخدام Kafka بدل RabbitMQ، اعتماد بنية Microservices.
- مثال على قرار لا يستحق ADR: تسمية متغير، اختيار مكتبة لعمل Validation بسيط، لون زر في الواجهة.
القاعدة الذهبية تبعتي: “إذا كان تغيير القرار في المستقبل سيكلفنا وقتًا وجهدًا كبيرًا، فهو يستحق ADR”.
تشريح سجل القرار (ADR): كيف تبني ذاكرة دائمة؟
جمال الـ ADRs في بساطة هيكلها. في قوالب كثيرة، لكن أشهرها وأكثرها عملية هو قالب Michael Nygard. احنا في فريقنا عدّلنا عليه شوي ليناسبنا، وهذا هو الجميل في الموضوع، بتقدر تفصّله على مقاسك. إليكم الهيكل الأساسي اللي بنستخدمه:
# [الرقم]. [عنوان القرار]
**التاريخ:** YYYY-MM-DD
**الحالة:** مقترح / مقبول / مرفوض / مُستبدَل
## السياق (Context)
(هون بنشرح المشكلة. شو القصة اللي خلتنا نفكر في هذا الموضوع أصلًا؟ شو المتطلبات والقيود؟ بنحكي القصة كاملة وكأننا بنشرحها لشخص جديد انضم للفريق اليوم).
## القرار (Decision)
(هون بنكتب القرار اللي توصلنا له بشكل واضح ومباشر. جملة واحدة أو اثنتين. "سنقوم باستخدام X لعمل Y").
## البدائل التي تم النظر فيها (Considered Alternatives)
* البديل الأول: (مزاياه وعيوبه)
* البديل الثاني: (مزاياه وعيوبه)
* ...
## النتائج (Consequences)
(هذا أهم قسم في الـ ADR كله. هون بنكون صريحين مع أنفسنا في المستقبل. بنكتب الآثار الإيجابية والسلبية لقرارنا.
- **إيجابيًا:** شو الكسب اللي حققناه؟ (مثلاً: سرعة في التطوير، أداء أفضل في جزئية معينة).
- **سلبيًا:** شو الثمن اللي دفعناه؟ شو المخاطر؟ (مثلاً: زيادة في تعقيد النظام، اعتماد على تقنية غير شائعة، ديون تقنية مستقبلية قبلنا فيها عن وعي).
مثال عملي من الميدان: اختيار بين RabbitMQ و Kafka
عشان الصورة تكون أوضح، هي مثال حقيقي (مع تغيير بعض التفاصيل) لـ ADR كتبناه في أحد المشاريع لما كنا بحاجة لنظام مراسلة (Messaging System).
# 004. اعتماد RabbitMQ لنظام المراسلة بين الخدمات
**التاريخ:** 2022-08-15
**الحالة:** مقبول
## السياق (Context)
مشروعنا يعتمد على معمارية الخدمات المصغرة (Microservices). نحتاج إلى طريقة تواصل غير متزامنة (Asynchronous) بين الخدمات لضمان عدم تأثر خدمة بتوقف خدمة أخرى. مثلاً، خدمة "الطلبات" تحتاج لإرسال إشعار لخدمة "الإشعارات" عند إنشاء طلب جديد، دون انتظار رد مباشر. الأولويات الحالية هي سهولة الإعداد، سرعة التطوير، ووجود دعم قوي في لغة البرمجة التي نستخدمها (Python).
## القرار (Decision)
سنقوم باعتماد RabbitMQ كوسيط رسائل (Message Broker) أساسي للتواصل غير المتزامن بين الخدمات.
## البدائل التي تم النظر فيها
* **Apache Kafka:** نظام قوي جدًا وممتاز لتدفق البيانات الضخمة (Streaming)، لكنه أكثر تعقيدًا في الإعداد والإدارة. يعتبر Overkill لاحتياجاتنا الحالية التي تتمحور حول طوابير مهام بسيطة.
* **AWS SQS:** حل ممتاز ومُدار بالكامل، لكنه يربطنا ببنية AWS التحتية بشكل كامل (Vendor lock-in)، ونحن نرغب في الحفاظ على إمكانية تشغيل نظامنا على أي بيئة سحابية في المستقبل.
* **بناء حل خاص:** خيار تم استبعاده فورًا لتعقيده العالي وعدم وجود أي مبرر له مع وجود حلول ناضجة في السوق.
## النتائج (Consequences)
- **إيجابيًا:**
- RabbitMQ سهل الإعداد والبدء به (مقارنة بـ Kafka).
- يمتلك مكتبات دعم ممتازة وناضجة في Python.
- يغطي كل حالات الاستخدام الحالية لدينا بكفاءة (Task Queues, Pub/Sub).
- الفريق لديه خبرة سابقة بسيطة فيه، مما يقلل من منحنى التعلم.
- **سلبيًا:**
- إذا تطورت احتياجاتنا في المستقبل نحو تحليل تدفقات البيانات الضخمة في الوقت الفعلي، قد لا يكون RabbitMQ هو الخيار الأمثل وقد نحتاج لإعادة تقييم هذا القرار (نحن نقبل هذا الدين التقني عن وعي).
- نحتاج لإدارة وتشغيل الـ Cluster الخاص بـ RabbitMQ بأنفسنا، مما يضيف عبئًا إداريًا بسيطًا على فريق البنية التحتية.
شايفين كيف؟ الآن، لو انضم مهندس جديد للفريق بعد سنتين وسأل “ليش بنستخدم RabbitMQ مش Kafka؟”، الجواب بكون على بعد كبسة زر، واضح، ومقنع.
نصائح أبو عمر الذهبية لتبني الـ ADRs بنجاح
تبني أي عملية جديدة في الفريق ممكن يكون صعب. من خبرتي، هاي شوية نصائح عملية بتساعدكم تبلشوا صح:
- ابدأ بسيطًا وصغيرًا: لا تحاولوا توثيق كل القرارات القديمة بأثر رجعي، هاي مهمة مستحيلة ومحبطة. ابدأوا من اليوم. أول قرار معماري كبير بتاخذوه، اكتبوا له أول ADR.
- اجعلها جزءًا من العملية: أفضل طريقة هي ربط الـ ADR بالـ Pull Request. لما تعمل تغيير كبير في الكود بناءً على قرار، ارفق معه الـ ADR الجديد أو المحدث. هيك بصير النقاش والمراجعة جزء من الـ Code Review.
- لا تبالغ في الإجراءات: كل ما تحتاجه هو مجلد في الـ Git Repo وقالب Markdown بسيط. لا تحتاج لأدوات معقدة أو برامج خاصة. البساطة هي سر النجاح.
- القالب مجرد اقتراح: القالب اللي حطيته فوق مش قرآن منزّل. عدّلوا عليه، احذفوا منه، زيدوا عليه ليناسب طريقة عمل فريقكم. المهم هو التقاط “السياق” و “النتائج”.
- شجع على النقاش: الـ ADR مش مجرد توثيق، هو أداة لبدء نقاش بنّاء. لما حدا يقترح ADR، الكل لازم يقرأه ويناقشه ويعطي رأيه قبل ما يتم “قبوله” رسميًا.
الخلاصة: من الذاكرة المفقودة إلى التاريخ الموثق ✅
في عالم تطوير البرمجيات السريع، ذاكرتنا كبشر هي أضعف حلقة في السلسلة. الاعتماد على ذاكرة الأفراد أو على سجلات الدردشة هو وصفة لكارثة محققة. سجلات القرارات المعمارية (ADRs) ما كانت مجرد حل تقني لمشكلتنا، بل كانت تحول ثقافي في طريقة تفكيرنا.
صارت قراراتنا مدروسة أكثر لأنه بنعرف إنها رح تتسجل وتصير مرجع. صار النقاش أغنى لأنه الكل بده يساهم في توثيق “النتائج” بشكل دقيق. وصار انضمام أي عضو جديد للفريق أسهل بكثير لأنه صار عنده “كتالوج” لتاريخ المشروع التقني يقرأه ويتعلم منه.
نصيحتي الأخيرة إلكم: لا تستنوا لحد ما تصير معكم كارثة زي اللي صارت معنا. ابدأوا اليوم. اكتبوا أول ADR لكم، حتى لو كان بسيطًا. مستقبل فريقكم، وسلامة عقلكم، رح يشكركم على هذا القرار. 🚀