عديم الحالة مقابل ذو الحالة: لماذا تعتمد استراتيجية النشر الخاصة بك على ذلك
لديك نسختان من نفس التطبيق قيد التشغيل. يقوم مستخدم بإرسال طلب. أي نسخة ستتعامل معه؟ إذا كانت الإجابة "أي منهما، لا يهم"، فأنت تنظر إلى تطبيق عديم الحالة (Stateless). إذا كانت الإجابة "يجب أن تكون نفس النسخة التي تعاملت مع طلبه السابق"، فأنت تتعامل مع تطبيق ذي حالة (Stateful).
هذا التمييز ليس أكاديمياً. إنه يحدد مدى سهولة نشر إصدار جديد، أو التوسع أثناء ارتفاع حركة المرور، أو التراجع عند حدوث خطأ ما. تكتشف العديد من الفرق هذا بالطريقة الصعبة: يبنون خط أنابيب نشر يعمل بشكل مثالي لخدمة واحدة، ثم يحاولون تطبيق نفس النهج على خدمة أخرى ويواجهون أعطالاً غير متوقعة.
ما الذي يجعل التطبيق عديم الحالة
التطبيق عديم الحالة لا يتذكر أي شيء بين الطلبات. كل طلب مستقل. يتلقى التطبيق المدخلات، ويعالجها، ويعيد النتيجة، وينسى كل شيء عن هذا التفاعل.
فكر في نقطة نهاية API تأخذ معرف منتج وتعيد تفاصيل المنتج من قاعدة بيانات. كل استدعاء مكتفي بذاته. لا يهتم التطبيق بمن اتصل به، أو ماذا اتصل به من قبل، أو ما سيحدث بعد ذلك. إذا قمت بتشغيل ثلاث نسخ من هذه الـ API خلف موازن تحميل، يمكن لأي نسخة التعامل مع أي طلب. إنها قابلة للتبديل.
الأمثلة الشائعة للتطبيقات عديمة الحالة تشمل:
يُظهر المخطط الانسيابي التالي الفرق بين مسارات النشر للتطبيقات عديمة الحالة وذات الحالة.
- واجهات برمجة تطبيقات REST التي تقرأ وتكتب في قاعدة بيانات مشتركة
- خدمات معالجة الصور التي تحول الملفات وتعيد النتائج
- خدمات المصادقة التي تتحقق من صحة الرموز المميزة دون تخزين بيانات الجلسة
- صفحات الويب المقدمة من الخادم التي تخزن كل الحالة في ملفات تعريف الارتباط أو معلمات URL
التطبيقات عديمة الحالة هي الأسهل في النشر والتوسع والاسترداد. يمكنك تشغيل إصدارات متعددة جنباً إلى جنب، وتحويل حركة المرور تدريجياً، والتبديل فوراً إذا حدث خطأ ما.
ما الذي يجعل التطبيق ذا حالة
التطبيق ذو الحالة يحتاج إلى تذكر شيء ما بين الطلبات. هذا الشيء يسمى حالة (State). يمكن أن يكون سلة تسوق، أو جلسة دردشة نشطة، أو رفع ملف قيد التقدم، أو جلسة مصادقة مستخدم مخزنة في ذاكرة الخادم.
ضع في اعتبارك تطبيق تجارة إلكترونية. يضيف مستخدم عناصر إلى سلة التسوق الخاصة به. بيانات سلة التسوق موجودة على الخادم الذي تعامل مع هذا الطلب. إذا ذهب الطلب التالي إلى خادم مختلف، فإن هذا الخادم لا يعرف شيئاً عن السلة. يرى المستخدم سلة فارغة. هذه مشكلة حالة.
التطبيقات ذات الحالة تخزن الحالة في عدة أماكن:
- في الذاكرة على خادم التطبيق (بيانات الجلسة)
- ملفات محلية على الخادم (الملفات المرفوعة، البيانات المؤقتة)
- قواعد بيانات مدمجة تعمل جنباً إلى جنب مع التطبيق
- مخابئ على مستوى التطبيق غير مشتركة بين النسخ
التحدي ليس في وجود الحالة. التحدي هو أين تعيش. إذا كانت الحالة مرتبطة بنسخة معينة، فلا يمكنك توجيه حركة المرور بحرية، أو استبدال النسخ، أو التوسع للأسفل دون فقدان البيانات.
كيف تبسط التطبيقات عديمة الحالة عملية النشر
نشر تطبيق عديم الحالة هو أمر مباشر. تقوم بتشغيل نسخ جديدة بالإصدار الجديد إلى جانب النسخ القديمة. يقوم موازن التحميل بتوجيه حركة المرور تدريجياً إلى النسخ الجديدة. بمجرد أن تكون كل حركة المرور على الإصدار الجديد، تقوم بإيقاف تشغيل النسخ القديمة.
إذا كان الإصدار الجديد يحتوي على خطأ، فإنك تعكس العملية. قم بتوجيه حركة المرور مرة أخرى إلى النسخ القديمة. لا ترحيل بيانات، لا تغييرات في المخطط، لا استرداد جلسة. الاسترجاع هو مجرد إعادة توجيه لحركة المرور.
التوسع يتبع نفس المنطق. بحاجة إلى سعة أكبر؟ قم بتشغيل المزيد من النسخ. انخفضت حركة المرور؟ قم بإزالة النسخ. لا توجد بيانات لإعادة توزيعها. كل نسخة متطابقة ويمكن التخلص منها.
هذه البساطة هي السبب في أن بنى الخدمات المصغرة تفضل التصميمات عديمة الحالة. يمكن نشر كل خدمة بشكل مستقل دون القلق بشأن ما تتذكره النسخ الأخرى.
لماذا تتطلب التطبيقات ذات الحالة مزيداً من العناية
نشر تطبيق ذي حالة يعني التعامل مع بيانات لا يمكن فقدانها أو إتلافها. إذا كان التطبيق يخزن الجلسات في الذاكرة، فإن استبدال جميع النسخ مرة واحدة يؤدي إلى تسجيل خروج كل مستخدم نشط. إذا كان التطبيق يكتب إلى ملفات محلية، فيجب ترحيل تلك الملفات أو يجب أن يكون الإصدار الجديد متوافقاً مع تنسيق البيانات القديم.
الاستراتيجيات الشائعة لنشر التطبيقات ذات الحالة تشمل:
نقل الحالة خارج التطبيق. قم بتخزين الجلسات في مجموعة Redis مشتركة أو قاعدة بيانات. قم بتخزين الملفات المرفوعة في تخزين كائنات مثل S3. هذا يحول التطبيق إلى تطبيق عديم الحالة من منظور النشر. يمكن استبدال التطبيق بحرية لأن الحالة تعيش في مكان آخر.
استخدام الجلسات الثابتة (Sticky Sessions). قم بتكوين موازن التحميل لإرسال نفس المستخدم إلى نفس النسخة. هذا يعمل ولكنه يخلق مشاكل أثناء عمليات النشر. لا يمكنك سحب حركة المرور من نسخة دون تعطيل المستخدمين النشطين. تصبح التحديثات المتداولة أبطأ لأنك يجب أن تنتظر حتى تنتهي صلاحية الجلسات.
استخدام StatefulSets أو المشغلين (Operators). تتعامل StatefulSets في Kubernetes ومشغلو قواعد البيانات مع تعقيد نشر التطبيقات ذات الحالة. يضمنون بدء تشغيل النسخ وإيقافها بالترتيب، والحفاظ على البيانات، واستقرار الهويات الشبكية. لكنها تتطلب فهم كيفية تصرف تطبيقك ذي الحالة المحدد.
التخطيط لترحيل البيانات. إذا كان الإصدار الجديد يغير كيفية تخزين البيانات، يجب أن يتضمن النشر خطوة ترحيل. يصبح الاسترجاع محفوفاً بالمخاطر لأن الإصدار القديم قد لا يفهم تنسيق البيانات الجديد. هذا شائع مع تغييرات مخطط قاعدة البيانات.
التأثير الحقيقي على فريقك
التمييز بين عديم الحالة وذو الحالة يؤثر على أكثر من مجرد قرارات تقنية. إنه يشكل كيفية عمل فريقك.
التطبيقات عديمة الحالة تسمح بنشر سريع ومتكرر. يمكن لأي عضو في الفريق نشر إصدار جديد دون القلق بشأن فقدان البيانات. الاسترجاعات آمنة وسريعة. هذا يقلل من الخوف من النشر ويشجع على إصدارات أصغر وأكثر تواتراً.
التطبيقات ذات الحالة تتطلب تنسيقاً دقيقاً. يجب التخطيط لعمليات النشر حول ترحيل البيانات، ومعالجة الجلسات، وتوافق الاسترجاع. غالباً ما تطور الفرق إجراءات خاصة للخدمات ذات الحالة: نوافذ النشر، بوابات الموافقة، خطوات التحقق اليدوية. هذا يبطئ التسليم.
إذا كانت مؤسستك تحتوي على كلا النوعين من التطبيقات، فلا تتوقع أن تعمل عملية نشر واحدة لكل شيء. خط أنابيب API عديم الحالة لن يناسب ترحيل قاعدة بيانات أو خدمة ذات حالة تدير جلسات المستخدمين.
قائمة مراجعة سريعة لنشرك القادم
قبل أن تخطط لنشر، اطرح هذه الأسئلة:
- هل يخزن التطبيق أي بيانات محلياً يجب أن تبقى بعد إعادة التشغيل؟
- هل جلسات المستخدم مخزنة في الذاكرة أم في مخزن خارجي مشترك؟
- هل يمكن لأي نسخة التعامل مع أي طلب، أم أن التوجيه يعتمد على أي نسخة لديها البيانات؟
- إذا قمت بالاسترجاع إلى الإصدار السابق، هل سيكون تنسيق البيانات لا يزال قابلاً للقراءة؟
- هل يمكنك تشغيل إصدارين جنباً إلى جنب دون تعارض في البيانات؟
إذا أجبت بـ "لا" على جميع الأسئلة المتعلقة بالتخزين المحلي واعتماد الجلسة، فلديك تطبيق عديم الحالة. انشر بحرية. إذا أجبت بـ "نعم" على أي منها، فأنت بحاجة إلى التخطيط لإدارة الحالة قبل تصميم استراتيجية النشر الخاصة بك.
الخلاصة
التطبيقات عديمة الحالة تمنحك الحرية. التطبيقات ذات الحالة تمنحك قيوداً. الخطأ هو معاملتها بنفس الطريقة. قبل أن تصمم خط أنابيب نشر، افهم أين تعيش بياناتك. إذا كانت تعيش داخل نسخة التطبيق، يجب أن تأخذ استراتيجية النشر الخاصة بك هذه البيانات في الاعتبار. إذا كانت تعيش في الخارج، يمكنك التعامل مع التطبيق على أنه قابل للتخلص والنشر بثقة.