در دنیای دیجیتال امروز، ساخت برنامههایی با قابلیت انعطافپذیری و کیفیت بالا، بسیار اهمیت دارد. برای ساخت برنامه با کیفیت، باید از بهترین شیوههای طراحی و پیادهسازی استفاده کرد. یکی از تصمیمات مهم در طراحی برنامهها، انتخاب بین دو نوع اپلیکیشن stateful وstateless است.
در این مقاله، به مقایسه و بررسی دو رویکرد stateful و stateless برای مدیریت وضعیت برنامه پرداخته شده و مزایا و معایب هر کدام مورد بررسی قرار گرفته است. همچنین، در ادامه مقاله، دلایل ترجیح stateless به stateful در کوبرنتیز (Kubernetes) بررسی شده و نکات مهمی در این زمینه مورد بحث و بررسی قرار گرفتهاند.
اپلیکیشنهای stateful
برنامههایstateful ، اطلاعات مربوط به نشست کلاینت (client session) مانند درخواستهای قبلی، وضعیت ورود/تأیید هویت و مواردی مانند عکس یا اطلاعات کاربران را ذخیره میکنند. در برخی سیستمهای stateful، این دادهها در سروری که برنامه در آن به اجرا درمیآید، ذخیره میشوند؛ اما در معماریهای سازمانی، دادهها بهجای سرور برنامه، در لایه حافظه نهان (Cache) ذخیره خواهند شد.
همچنین برنامههای stateful دارای پایگاه داده هستند، اما وقتی درخواست جدیدی از کلاینت دریافت میشود، برنامه از state data ذخیره شده خود بهعنوان بستر پاسخدهی کمک میگیرد تا در پردازش درخواستهای بعدی کلاینت، راحتتر باشد. این ویژگی، فرآیند پردازش را سریعتر و کارآمدتر میکند، اما تنها درصورتی موثر است که سرور به اندازه کافی قدرتمند و منابع لازم برای پردازش ترافیک را در اختیار داشته باشد.
نگاهی عمیقتر به اپلیکیشنهای stateful
برنامههای stateful، برای پردازش تعاملات (transactions) جدید، به دادههای client session ذخیرهشده، وابسته هستند. در این برنامهها، هنوز از پایگاه داده برای ذخیرهسازی back-end استفاده میشود، اما از سروری که برنامه روی آن در حال اجراست، برای ذخیرهسازی دادههای نشستهای قبلی استفاده میکنند. این دادههای نشست کلاینت (state data) این امکان را به برنامه میدهند که تعاملات بعدی را با پیشزمینه تعاملات پیشین، پردازش کند.
برنامههای وب سنتی از نوع برنامههای stateful هستند که از نشستهای راه دور (remote sessions) برای حفظ وضعیت خود کمک میگیرند. در این روش، تمامی اطلاعات نشست در سرور و با توجه به اصل اولیه توسعه REST که توسط Roy T. Fielding معرفی شده، ذخیره میشوند.
بگذارید برای درک بهتر مفهوم برنامههای stateful با یک مثال پیش برویم. فرض کنید سالهاست که شما از یک فروشگاه محلی نزدیک خانه خودتان خرید میکنید. فروشنده شما را میشناسد، بنابراین هر بار نیازی به ارائه مدارک شخصی ندارید.
فروشگاه همچنین سوابق خرید شما را در داخل فروشگاه نگهداری میکند و از جانب شما نیازی به ذخیره هیچ دیتایی(state) نخواهد بود. بدین ترتیب، میتوانید بهسادگی به فروشگاه مراجعه کنید، کالاهای موردنیاز خود را خریداری و هزینه آن را بپردازید. این سیستم تا زمانی که فروشگاه قادر به پردازش های متعدد در یک لحظه باشد، سریع و کارآمد است.
مثال نزدیکتر به واقعیت از اپلیکیشنهای stateful ، یک سرویس وب stateful است. این سرویس اطلاعات تأیید هویت کاربر را بر روی سرور ذخیره میکند و کاربرها را با وضعیت “متصل” یا “قطع شده” برچسب میزند و اطلاعاتی را درمورد درخواستهای قبلی از همان کاربرها نگه میدارد.
این سرویس، همه این اطلاعات را بهعنوان پیشزمینه پاسخدهی درخواستهای بعدی مشتریها در نظر میگیرد. اگر یک کاربر درخواستی برای بازیابی اطلاعات حساب خود داشته باشد، سرویسstateful شناسه و وضعیت متصل/قطع شده کاربر را تعیین میکندبنابراین، ویژگیهای اساسی برنامههایstateful شامل استفاده از پایگاه داده مانند هر برنامه دیگری است، با این تفاوت که آنها اطلاعات را روی سرور خود نگهداری میکنند. این ویژگی باعث میشود برنامههایstateful سریعتر و کارآمدتر عمل کند.
اپلیکیشنهای stateless
در برنامههایStateless ، اطلاعات وضعیت کاربران روی سروری که برنامه در آن قرار دارد، ذخیره نمیشوند. بهجای آن، تمام دادهها در پایگاه داده پشتیبانی شده و یا در فضای دیگری ذخیره میشود state دادهها در کش کاربرانی که با برنامه تعامل دارند، نگهداری میشود.
در برنامههای وب، برنامههایStateless میتوانند به همان شکلی که برنامههایstateful کار میکنند، عمل کنند. برای این کار، برنامهنویسان میتوانند HTTP را به گونهای تغییر دهند که برنامههای Stateless رفتاری شبیه برنامههایstateful داشته باشند. یک مثال از این کار، نمایش نام کاربری پس از ورود موفق در نوار ناوبری وبسایت است. در اینجا، از یک شناسه (معمولاً یک کوکی) برای نگهداری وضعیت داده کمک گرفته میشود که مشتری آن را در سیستم خود ذخیره میکند.
برنامههایStateless ، اگرچه گاهی باعث کاهش سرعت برخی از انواع تعاملات کاربری میشوند، اما از نظر میزان مقیاسپذیری معمولا در مقایسه با اپلیکیشنهای stateful وضعیت بهتری دارند.
نگاهی عمیقتر به اپلیکیشنهای stateless
برنامهStateless هیچ دادهای که مربوط به تعاملات گذشته است را در سرور خود ذخیره نمیکند. هر تعامل با کاربر را مانند یک کاغذ سفید و بدون اطلاعاتی از تعاملات گذشته، میپذیرد.
در بیشتر موارد، منظور از Stateless به معنای عدم وجود داده نیست و بیشتر منظور این است که در این نوع از اپلیکیشنها دادهها در جای دیگری نگهداری میشود. به عنوان مثال، وقتی از یک دستگاه خرید خودکار نوشابه استفاده میکنید، خودتان دیتا را حفظ میکنید. بعد از خرید یک نوشیدنی، دستگاه به خاطر نمیآورد که چه نوع نوشیدنی خریداری کردهاید، اما شما به دلیل نگهداشتن آن در دستان خود، به یاد دارید. در این رابطه، بهتر است بگوییم که برنامهStateless ، دادههای خود را بهصورت خارجی ذخیره میکند تا در سرور نگهداری نشود. به همین دلیل، بسیاری از برنامهها (کلاینتها) روی تلفن همراه یا کامپیوتر شما، یک حافظه نهان (cashe) دارند. این حافظه نهان دادههای وضعیت را در سیستم محلی شما ذخیره میکند تا برای تعاملات بعدی، مورد استفاده قرار گیرند.
لئونارد ریچاردسون و سام روبی بهترین توصیفی از سیستمهای stateless را ارائه دادند که میگویند: “نداشتن state به معنای این است که هر درخواست HTTP در استقلال کامل انجام میشود. وقتی کلاینت یک درخواست HTTP میفرستد، تمام اطلاعات لازم برای سرور، جهت تولید پاسخ درخواستی در آن وجود دارد. سرور هرگز به اطلاعات درخواستهای قبلی وابسته نیست. اگر آن اطلاعات مهم بودند، کلاینت باید آنها را در درخواست جدید خود نیز ارسال میکرد.”
یک برنامه stateless به عنوان یک ابزار یا واسط بینام برای کاربران جهت ارتباط با پایگاه دادهها (و شاید دیگر سرویسها) عمل میکند. با توجه به این که state در برنامه وجود ندارد، یک متعادل کننده بار (Load balancer) میتواند نمونههای (موجودیتهای قابل استفاده) جدید را بدون هیچ محدودیتی بلاک کرده و درخواستهای کاربران را بین این نمونهها توزیع کند. این قابلیت، به سیستم امکان مقیاسپذیری و مدیریت هر سطح ترافیک را خواهد داد.
تفاوت اپلیکیشنهای stateless و stateful
هر کدام از این اپلیکیشنها کاربردهای خاص خود را دارند. اما نرم افزارهای مدرن بیشتر بهصورتStateless طراحی شدهاند؛ زیرا مقیاسپذیری یکی از فاکتورهای اساسی در دنیای تکنولوژی امروز است. هفت تفاوت اصلی به شرح زیر هستند:
- نحوه کار: در حالی که برنامههای Stateless بهصورت مستقل و بدون در نظر گرفتن درخواست قبلی کار میکنند. اپلیکیشنهای Stateful متناسب با وضعیت کنونی واکنش میدهند.
- دادههای ذخیره شده: در صورتی که وب سرور، داده را برای شناسایی کاربر به عنوان یک کلاینت همیشگی ذخیره کند، سرویسStateful است؛ در حالی که در برنامههای Stateless، سرور دادهها را در یک پایگاه داده ذخیره کرده تا هر زمان که نیاز به اتصال دارد، کاربر را تأیید کند.
- واکنش به کلاینتها: در برنامههایStateful ، سرور تصور میکند که کلاینت تنها یک دستگاه ابله است! در حالی که در برنامههای Stateless، سرور کلاینت را یک دستگاه هوشمند تصور کرده که به هیچ شکل به سرور وابسته نیست.
- درخواستها: در برنامههای Stateless، درخواستها (requests ) خودکفا هستند. به عبارت دیگر، همه چیز در داخل درخواست قرار دارد و در دو مرحله مجزا “request” و “response” پردازش میشود، در حالی که در برنامههای Stateful ، درخواستها همیشه بر اساس وضعیت سمت سرور و وضعیت کلاینت پردازش میشود و برخی اطلاعات ممکن است در پاسخهای قبلی ذخیره شود.
- تغییر وضعیت: در برنامههایStateful ، تغییر وضعیتی که به سمت سرور فرستاده شده ، به عنوان وضعیت جدید است؛ در حالی که در برنامههای Stateless، وضعیت همیشه در یک پایگاه داده ثبت و هرگونه تغییر، تنها از طریق ارسال درخواست جدید انجام میشود.
- پردازش: در برنامههای Stateless، هر درخواست به صورت مستقل مورد پردازش قرار میگیرد، در حالی که در برنامههایStateful ، پردازش درخواستها به صورت پشت سر هم جلو میرود.
- شناسایی: در برنامههایStateful ، شناسایی کاربر با استفاده از اطلاعات شناسایی موجود در هر درخواست است، در حالی که در برنامههای Stateless، شناسایی کاربر با استفاده از توکنهای امنیتی صورت میپذیرد.
- وضعیت درخواستها: در برنامههای Stateless، هیچ گونه وضعیتی در بین درخواستها ذخیره نمیشود، در حالی که در برنامههایStateful ، اطلاعات هر وضعیت بین درخواستها در سمت سرور ذخیره میشود.
در کل، برنامههای Stateless، بهصورت مستقل و مقیاس پذیر طراحی شدهاند و در محیطهای بزرگ، مفیدتر هستند. در حالی که برنامههایStateful ، به صورت سنتی طراحی شدهاند و برای پروژههای کوچک و سادهتر به کار میآیند.
مزایای اپلیکیشنهای stateless
پنج مزیت اصلی برنامههای Stateless به شرح زیر است:
- حذف هزینههای مربوط به ایجاد/استفاده از نشست.
- مقیاسپذیری بالا برای نیازهای مدرن کاربران.
- اضافه/حذف کردن نمونههای جدیدی از یک برنامه بر اساس درخواست.
- امکان توافق در کاربردهای مختلف.
- سادگی نگهداری و توسعه اپلیکیشن
معایب اپلیکیشنهای stateless
برنامههای Stateless محدودیتهایی دارند و در زمان طراحی و استقرار آنها در Kubernetes یا سایر پلتفرمهای مشابه، باید به این محدودیتها توجه داشت. در زیر چند محدودیت برنامههای Stateless آورده شده است:
- ثبات داده: برنامههای Stateless قابلیت ذخیرهسازی هیچ گونه stateای را در سمت خود ندارند. به این معنا که هر دادهای که نیاز به ثبت دارد، باید در یک دیتابیس جداگانه ذخیره شود. این ویژگی میتواند باعث کاهش سرعت و سایر مشکلات عملکردی شود، به ویژه اگر دیتابیس از راه دور قابل دسترس باشد.
- مدیریت نشست: برنامههای Stateless هیچ اطلاعاتی از وضعیت نشست را حفظ نمیکنند، به این معنی که نمیتوانند نشست کاربر را پیگیری و یا اطلاعات مربوط به هر درخواست را در بین درخواستها نگهداری کنند. این موضوع ممکن است پیادهسازی ویژگیهایی مانند سبد خرید یا تأیید هویت کاربر را به سمت دشواری ببرد.
- تعاملات پیچیده: برنامههای Stateless برای پردازش تعاملات پیچیده که نیاز به حفظ وضعیت در بین چندین درخواست را دارند، مناسب نیستند. به عنوان مثال، برای پردازش تراکنشهای مالی، نیاز است تا موجودی حساب کاربر را در حالتی که بین چندین درخواست مختلف تغییر کرده، حفظ کنیم. این کار در یک محیط Stateless می تواند کاری دشوار باشد.
- سازگاری داده: برنامههای Stateless برای حفظ وضعیت، به دادههای خارجی نیاز دارند تا وضعیت را حفظ کنند، اما اگر چندین نمونه از برنامه به دادههای یکسان دسترسی داشته باشند، ممکن است باعث مشکلات سازگاری شود. برای اطمینان از سازگاری داده و جلوگیری از رویدادهای دادهای، نیاز به طراحی و هماهنگی دقیق دارند.
در طراحی برنامههای Stateless، مهم است که این محدودیتها را در نظر داشته باشید. هرچند که این برنامهها مزایای چشمگیری دارند، اما ممکن است برای هر استفادهای مناسب نباشند.
stateless یا stateful؟ کدام گزینه برای شما مناسبتر است؟
انتخاب بین برنامههای Stateless و Stateful ، نیاز به بررسی دقیق چندین عامل دارد. به عنوان مثال:
- اگر برنامه شما نیاز به همزمانی (concurrency) بالا و انعطاف پذیری دارد، برنامه Stateless بهترین گزینه خواهد بود. برنامههای Stateless میتوانند حجم زیادی درخواست را پردازش کنند و با خوبی مقیاسپذیرند، بنابراین برای برنامههایی که نیاز به چابکی و انعطاف پذیری دارند، گزینه مناسبی هستند.
- اگر شما به پردازش دادههای بلادرنگ (real-time) و سازگاری دادهها نیاز دارید، برنامه Stateful ممکن است گزینه بهتری باشد. برنامههای Stateful میتوانند سازگاری دادهها را حفظ کنند و عملکرد قابل پیشبینی را ارائه دهند؛ بنابراین برای برنامههایی که به پردازش دادههای بلادرنگ یا کارهای مشارکتی نیاز دارند، مناسب هستند.
- اگر ثبات داده برای برنامه شما حائز اهمیت است، برنامه Stateful پیشنهاد معقولتری است. برنامههای Stateful میتوانند دادهها را بین درخواستها ذخیره کرده و اطمینان حاصل کنند که دادهها همیشه ثابت و در دسترس هستند.
- بسته به میزان حساسیت دادههایی که دارید، مسائل مربوط به امنیت و حفظ حریم خصوصی کاربران شما باید چالشها و ملاحظات مرتبط به هر رویکرد را مد نظر داشته باشید.
در نهایت، انتخاب بین برنامههای Stateless و یا Stateful به نیازهای ویژه برنامه شما بستگی دارد. بررسی دقیق مزایا، چالشها و ملاحظات هر رویکرد، اطلاعات لازم را برای تصمیمگیری فراهم میکند.
چرا کوبرنتیز اپلیکیشنهای Stateless را به اپهای Stateful ترجیح میدهد؟
در Kubernetes بهطور کلی توصیه میشود که برنامهها Stateless طراحی شوند؛ به این معنا که برنامه هیچ state یا دادهای را در nodeهایی که در آن اجرا میشود، ذخیره نکند. بهجای آن، همه دادهها در یک فضای ذخیرهسازی مرکزی یا یک سیستم ذخیرهسازی توزیعشده مانند پایگاه داده، ذخیره میشوند.
چندین دلیل وجود دارد که Kubernetes به برنامههای Stateless ارجعیت میدهد:
- مقیاسپذیری: برنامههای Stateless به دلیل عدم ذخیره هیچ stateای در nodeای که در آن اجرا میشوند، برای افزایش مقیاسپذیری راحتتر هستند. این بدان معناست که میتوانید نمونههای جدید برنامه را بدون نگرانی از مسائل هماهنگی دادهها، ایجاد کنید.
- استحکام: برنامههای Stateless بهدلیل ذخیره نکردن هیچ stateای در سطح محلی، در برابر مسائل مربوط به خرابی و از بین رفتن مقاومت بیشتری نشان میدهند. اگر یک از بین برود، Kubernetes میتواند بهطور خودکار یک نمونه جدید از برنامه را در node دیگری ایجاد کند، بدون از دست دادن هیچ دادهای!
- توسعه و بهروزرسانی: برنامههای Stateless برای بهروزرسانی و مراحل توسعه بهتر هستند، زیرا هیچ state محلی برای جابهجایی وجود ندارد. شما میتوانید بهسادگی نمونههای قدیمی را با نمونههای جدید جایگزین کنید، بدون اینکه نگران مسائل هماهنگی داده باشید.
- قابلیت جابهجایی: برنامههای Stateless بیشترین قابلیت جابهجایی را دارند، زیرا به هیچ state لوکال وابستگی ندارند. این بدان معناست که بهراحتی بین انواع مختلف nodeهای کوبرنتیز و یا ارائهدهندگان ابری متفاوت منتقل میشود.
در کل، برنامههای Stateless در کوبرنتیز بهعنوان یک الگوی طراحی، توصیه میشوند؛ زیرا مزایای بسیاری از نظر مقیاسپذیری، استحکام، بهروزرسانی و جابهجایی دارند؛ اما در مواردی به برنامههای Stateful نیاز است، مانند پایگاه دادهها یا فضاهای دادهای دیگر که به ذخیرهسازی پایدار نیاز دارند. در این موارد، کوبرنتیز ویژگیهایی مانند StatefulSets و حجمهای ماندگار (Persistent Volumes) را برای کمک به مدیریت برنامههای Stateful فراهم میکند.
معمولا تغییر اپلیکیشنها از حالت سنتی و stateful به stateful میتواند کار هزینهبری باشد یا زمان زیادی از شما بگیرد. اما مزایا و انعطافی که کوبرنتیز فراهم میکند میتواند در درازمدت بسیار ارزشمندتر باشد.