در برنامه نویسی، state به وضعیت یک سیستم، کامپوننت یا اپلیکیشن در یک نقطه خاص از زمان اشاره میکند. به عنوان یک مثال ساده، اگر از parsdev.com خرید میکنید، اینکه آیا در حال حاضر وارد سایت شدهاید یا چیزی در سبد خرید خود ذخیره کردهاید، نمونههایی از state هستند.
state نشان دهنده داده هایی است که ذخیره شده و برای پیگیری وضعیت فعلی برنامه استفاده میشود. درک و مدیریت state برای ساخت برنامههای کاربردی وب تعاملی و پویا بسیار مهم است.
مفهوم state در معماری از مرزهای بسیاری عبور میکند. الگوهای طراحی (مانند REST و GraphQL)، پروتکلها (مانند HTTP و TCP)، فایروالها و توابع میتوانند stateful یا stateless باشند. اما اصل زیربنایی state در همه این حوزهها یکسان است.
این مطلب توضیح خواهد داد که state به چه معناست و معماریهای stateful و stateless را با برخی قیاسها، مزایا و معایب توضیح میدهد.
معماری Stateful چیست؟
تصور کنید برای خوردن پیتزا به یک رستوران رفتهاید. در این رستوران فقط یک گارسون وجود دارد و گارسون از شماره میز شما، آنچه که سفارش دادهاید، ترجیحات شما بر اساس سفارشهای گذشته، مانند نوع خمیر پیتزا که دوست دارید یا تاپینگهایی که به آن حساسیت دارید و غیره یادداشتهای دقیقی بر میدارد.
تمام این اطلاعاتی که پیشخدمت در دفترچه یادداشت خود می نویسد، وضعیت مشتری است. فقط پیشخدمتی که به شما خدمات میدهد به این اطلاعات دسترسی دارد. اگر میخواهید در سفارش خود تغییری ایجاد نموده یا بررسی کنید که چگونه انجام میشود، باید با همان گارسونی صحبت کنید که سفارش شما را دریافت کرده است. اما از آنجایی که فقط یک پیشخدمت وجود دارد، مشکلی نیست.
حالا، فرض کنید رستوران شروع به شلوغ شدن کند. پیشخدمت شما باید به مهمانان دیگر پاسخ دهد پس گارسونهای بیشتری شروع به کار میکنند. اکنون میخواهید وضعیت سفارش خود را بررسی کنید و یک تغییر کوچک در آن ایجاد کنید مثلا یک خمیر ساده به جای یک خمیر پنیری. فقط گارسون موجود با کسی که در ابتدا سفارش شما را گرفته متفاوت است.
این گارسون جدید جزئیات سفارش شما را ندارد، این state شماست. پس آنها نمیتوانند وضعیت سفارش شما را بررسی یا تغییراتی در آن ایجاد کنند. رستورانی که به این شکل عمل میکند، جایی که فقط پیشخدمتی که در ابتدا سفارش شما را دریافت کرده است میتواند بهروزرسانیهایی در مورد آن به شما داده یا تغییراتی در آن ایجاد کند، از یک طراحی stateful پیروی میکند.
به طور مشابه، یک برنامه stateful سروری خواهد داشت که داده های مشتریان (یعنی state آنها) را به خاطر می آورد. تمام درخواستهای آینده با استفاده از لود بالانسر با فعال کردن sticky sessions به همان سرور هدایت میشوند. به این ترتیب سرور همیشه از کلاینت آگاه است.
نمودار زیر دو کاربر مختلف را نشان می دهد که سعی می کنند از طریق یک لود بالانسر به یک وبسرور دسترسی پیدا کنند. از آنجایی که وضعیت برنامه در سرورها نگهداری میشود، کاربران همیشه باید برای هر درخواست منفرد به همان سرور هدایت شوند تا وضعیت حفظ شود.
Sticky sessions پیکربندی است که به لود بالانسر اجازه میدهد تا درخواستهای کاربر را در طول مدت جلسه به طور مداوم به همان سرور backend هدایت کند. این برخلاف لود بالانسینگ سنتی است، که در آن درخواستهای کاربر را میتوان به هر سرور بکاند موجود در یک الگوی توزیع بار چرخشی یا دیگر الگوی توزیع بار هدایت کرد.
مشکل معماری stateful چیست؟ تصور کنید یک رستوران به این شکل اداره میشود. در حالی که ممکن است برای یک رستوران کوچک خانوادگی با تعداد کمی مشتری ایدهآل و آسان اجرا شود، اما چنین طراحی قابل تحمل و مقیاسپذیر نیست.
اگر گارسونی که سفارش مشتری را گرفته است، شرایط اضطراری داشته و باید آنجا را ترک کند، چه اتفاقی میافتد؟ تمام اطلاعات مربوط به آن سفارش در اختیار آن گارسون است. این امر تجربه مشتری را مختل میکند، زیرا هر گارسون جدیدی که برای جایگزینی گارسون قدیمی وارد می شود، از سفارشات قبلی اطلاعی ندارد. این طرحی است که تحمل خطا را ندارد.
خرید سرور مجازی در پنج موقعیت جغرافیایی ایران، ترکیه، هلند، آلمان و آمریکا با قابلیت تحویل آنی در پارسدو فراهم است.
همچنین، توزیع درخواستها به گونهای که همان مشتری بتواند تنها با یک پیشخدمت صحبت کند، به این معنی است که بار روی گارسونهای مختلف به طور مساوی توزیع نمیشود. برخی از پیشخدمتها غرق در درخواست میشوند و بعضی دیگر کاری برای انجام دادن نخواهند داشت و نمیتوانند برای کمک وارد عمل شوند. پس، این یک طراحی غیر مقیاس پذیر است.
به طور مشابه، ذخیره دادههای وضعیت برای مشتریان مختلف در سرورهای مختلف قابل تحمل خطا و مقیاسپذیر نیست. خرابی سرور منجر به از دست رفتن دادههای state میشود. بنابراین، اگر کاربری وارد سیستم شده باشد و به عنوان مثال در حال بررسی یک سفارش بزرگ در Amazon.com باشد، کاربر مجبور به احراز هویت مجدد و سبد کاربر خالی خواهد بود. آنها باید دوباره وارد سیستم شوند و سبد خود را از ابتدا پر کنند که مصداق یک تجربه کاربری ضعیف است.
دستیابی به مقیاس پذیری در زمانهای پیک فروش مانند بلک فرایدی یا جشن نوروز با طراحی stateful نیز دشوار خواهد بود. سرورهای جدید به گروه مقیاسبندی خودکار اضافه خواهند شد، اما از آنجایی که جلسات چسبنده فعال هستند، کلاینتها به همان سرور هدایت میشوند و باعث میشود که آنها تحت فشار قرار بگیرند، که میتواند باعث افزایش زمان پاسخ و تجربه کاربری ضعیف شود.
معماری Stateless بسیاری از این مشکلات را حل میکند.
معماری Stateless چیست؟
معماری Stateless یک اصطلاح گیج کننده است، زیرا به این معنی است که سیستم بدون وضعیت است. با این حال، معماری Stateless به این معنی نیست که اطلاعات وضعیت ذخیره نمیشود بلکه به این معنی است که اطلاعات وضعیت، خارج از سرور ذخیره میگردد. بنابراین، حالت Stateless فقط برای سرور اعمال میشود.
به مثال رستوران برگردیم، گارسونهای یک رستوران Stateless را میتوان بهعنوان افراد کاملا فراموشکار تصور کرد. آنها مشتریان قدیمی را نمیشناسند و نمی توانند به یاد بیاورند که چه چیزی سفارش دادهاید یا چگونه پیتزای خود را دوست دارید. آنها به سادگی سفارشات مشتریان را در یک سیستم جداگانه، مثلا یک تبلت یا کامپیوتر، که برای همه پیشخدمتها قابل دسترسی است، یادداشت میکنند. سپس میتوانند به آن سیستم برگردند تا جزئیات سفارش را دریافت و در صورت لزوم تغییراتی در آن ایجاد کنند.
با ذخیره وضعیت (state) سفارش مشتری در یک سیستم مرکزی که توسط سایر پیشخدمتها قابل دسترسی است، هر پیشخدمتی می تواند به هر مشتری سرویس بدهد.
در معماری Stateless، درخواست های HTTP از یک کلاینت میتواند به هر یک از سرورها ارسال شود.
State معمولا در یک پایگاه داده جداگانه ذخیره میشود که توسط همه سرورها قابل دسترسی است. این یک معماری قابل تحمل و مقیاس پذیر ایجاد میکند زیرا وب سرورها را می توان در صورت نیاز اضافه یا حذف کرد، بدون اینکه روی دادههای state تاثیر بگذارد.
بار(load) هم به طور مساوی در بین تمام سرورها توزیع میشود، زیرا لود بالانسر نیازی به پیکربندی sticky session برای مسیریابی مشتریان مشابه به سرورهای مشابه ندارد.
نمودار زیر دو کاربر مختلف را نشان میدهد که سعی میکنند از طریق یک لود بالانسر به یک وبسرور دسترسی پیدا کنند. از آنجایی که وضعیت برنامه به طور جداگانه از سرورها نگهداری می شود، کاربران میتوانند به هر یک از سرورها هدایت شوند، که سپس اطلاعات وضعیت را از یک پایگاه داده خارجی قابل دسترسی توسط هر دو سرور دریافت میکند.
به طور معمول، دادههای state در یک کش مانند Redis، در حافظه ذخیره میشوند. همانطور که در اینجا توضیح داده شد، ذخیره دادههای حالت در حافظه، زمان خواندن و نوشتن را در مقایسه با ذخیره آن روی دیسک بهبود میبخشد.
جمع بندی
این مطلب نحوه عملکرد اپلیکیشنهای stateful و Stateless و وضعیت و معاوضه هر دو را شرح داده است. اما اصل Statefulness و Statelessness فراتر از اپلیکیشنهای وب اعمال میشود.
اگر به پروتکل های شبکه به عنوان مثال نگاه کنیم، HTTP یک پروتکل Stateless است. این بدان معناست که هر درخواست HTTP از یک کلاینت به یک سرور مستقل است و هیچ اطلاعی از درخواستهای قبلی یا زمینه آنها ندارد. سرور با هر درخواست به عنوان یک تراکنش ایزوله و مجزا برخورد میکند و اطلاعاتی در مورد وضعیت مشتری بین درخواستها نگهداری نمیکند.
وضعیت (state) یا بر روی سرورها (معماری stateful) یا در یک پایگاه داده جداگانه در خارج از سرورها (Stateless) نگهداری میشود. خود پروتکل HTTP وضعیت را نگهداری نمیکند.
برخلاف ماهیت بدون حالت HTTP، پروتکل TCP اتصال گرا و stateful است. یک ارتباط بین دو دستگاه (معمولا یک کلاینت و یک سرور) برقرار کرده و یک کانال ارتباطی مداوم را تا پایان اتصال حفظ مینماید.
همین منطق در مورد فایروالها نیز صدق برقرار است که میتوانند stateful یا Stateless باشند.
در AWS، یک گروه امنیتی یک فایروال مجازی است که ترافیک ورودی و خروجی ماشینهای مجازی یا نمونههای موجود در محیط ابری را کنترل میکند. گروه های امنیتی stateful هستند. هنگامی که یک جریان ترافیک ورودی خاص را مجاز میکنید، جریان ترافیک خروجی مربوطه نیز به طور خودکار مجاز است. به عبارت دیگر، وضعیت اتصال ردیابی میشود.
لیستهای کنترل دسترسی به شبکه (NACL) برای کنترل ترافیک ورودی و خروجی در سطح سابنت در AWS استفاده میشود. NACLها دارای معماری Stateless هستند. Stateless به این معنی است که شما باید به صراحت قوانین(rules) را برای ترافیک ورودی و خروجی تعریف کنید.
بر خلاف گروههای امنیتی، که در آنها ترافیک پاسخ بهطور خودکار مجاز است وقتی ترافیک ورودی را مجاز میکنید، NACL از شما میخواهد که قوانین جداگانهای برای ترافیک ورودی و خروجی تعریف کنید.
توابع و الگوهای طراحی نیز می توانند stateful یا Stateless باشند.
اصل کلیدی پشت چیزی که stateful دارد این است که حافظه یا دانش کاملی از تماسها یا درخواستهای قبلی داشته باشد، در حالی که چیزی که Stateless است حافظه یا اطلاعی از تماسها یا درخواستهای قبلی ندارد.
امیدواریم درک خوبی از نحوه عملکرد برنامههای stateful و Stateless داشته باشید و بتوانید تصمیم بگیرید که کدام گزینه برای برنامههای شما بهترین است.
نظرتون برامون مهمه شما اولین نظر رو بنویسید