بررسی اپلیکیشن های Monolithic که در قالب یک Container استفاده می‌شوند

استفاده کردن از Container‌ ‌ها برای مدیریت کردن روال Deployment مربوط به Monolithic Application ها مزیت‌های زیادی دارند. یکی از مهمترین مزیت ها سرعت بالایی است که در مدیریت Container ها نسبت به مدیریت ماشین های مجازی دیگر وجود دارد به طور کلی Scale کردن ماشین های مجازی نسبت به استفاده کردن از Container ‌ها زمان بیشتری را خواهد برد. در زمان استفاده کردن از این تکنیک روال مدیریت کردن اپلیکیشن به عنوان بخشی از روال مدیریت کردن ماشین مجازی مورد استفاده قرار می‌گیرند.


علاره براین موضوع Deploy کردن به روز رسانی ها در قالب Docker Image ها نیز سرعت بیشتری دارد و از لحاظ استفاده از پهنای باند شبکه نیز بسیار کارآمدتر است. Docker Image ها اغلب در کسری از ثانیه آغاز می‌شوند و سرعت فوق العاده بالایی دارند. علاوه بر این از بین بردن یک Docker Image به سادگی با استفاده از دستور Docker Stop اتفاق می‌افتد و در کسری از ثانیه نیز تکمیل خواهد شد.

از آنجایی که Container ها به صورت درونی Immutable و یا غیر قابل تغییر هستند هیچ گاه نیاز به نگران شدن برای ماشین های مجازی فاسد شده نباشید. البته Update Script ها ممکن است که پیکربندی های خاص و یا حتی فایل هایی را بر روی دیسک فراموش کرده و ردپایی را از خود به جا بگذارند. علاوه بر این موضوع استفاده کردن از Container Docker ها برای Deploy کردن اپلیکیشن های Monolithic بسیار ساده تر خواهد بود. این موضوع باعث می‌شود که continuous Integration و continuous deployment و Pipeline های مربوط به این دو بهبود پیدا کنند و موفقیت بیشتری را در روال Deployment و رفتن به سمت Production کسب کنید. به عبارت دیگر جملاتی از قبیل این برنامه بر روی سیستم من کار می‌کرد چرا بر روی این سیستم کار نمی‌کند را دیگر نخواهید شنید.

لطفاً فراموش نکنید که معماری مایکروسرویسی نیز مزیت های بسیاری را نسبت به معماری Monolithic در اختیار شما قرار می دهد. در این رابطه می‌تواند در زمینه آموزش ویدیویی شروع به کار با معماری مایکروسرویسی دیدن کنید. مزیت های معماری مایکروسرویسی به همراه پیچیدگی‌های بیشتر این معماری می بایست در نظر گرفته شوند. در بسیاری شرایط این پیچیدگی‌ها و هزینه‌های بیشتر از مزیت هایی که معماری مایکروسرویسی در اختیار شما قرار می دهد بیشتر است. بنابراین در چنین شرایطی توصیه می‌کنیم که از همان معماری Monolithic استفاده کنید و برنامه‌ها را در یک Container تک و نهایتاً در چندین Container اجرا نمایید.

در شرایطی نیز ممکن است یک اپلیکیشن Monolithic نتواند به چندین مایکروسرویس مختلف تجزیه گردد. مایکروسرویس ها می بایست بتوانند مستقل از یکدیگر کار کنند و قابلیت resilient بودن برنامه را نیز فراهم نمایند. بنابراین اگر نمی توانید ویژگی های مختلف برنامه را در قالب مایکروسرویس های جداگانه تشکیل بدهید ممکن است که استفاده کردن از معماری مایکروسرویسی پیچیدگی برنامه را بیشتر کند.

علاوه به این موضوع یک اپلیکیشن ممکن است نیازی به Scale کردن ویژگی های مختلف خود به صورت مستقل از یکدیگر نداشته باشند. به عبارت دیگر خیلی از اپلیکیشن ها در زمان Scale نشدن می‌توانند Alone و یا کپی بشوند و یک اپلیکیشن به صورت کامل و در قالب یک واحد تک Scale بگردد. در چنین شرایطی نیز استفاده کردن از معماری مایکروسرویسی برای شکستن یک نرم افزار کامل به چندین سرویس کوچک تر مزیت زیادی را در اختیار شما قرار نمی دهد. بنابراین بهتر است در چنین شرایطی نیز از همان معماری Monolithic استفاده کنید.

موضوع دیگر این است که در روند توسعه دادن یک اپلیکیشن ممکن است از همان ابتدای کار درک درستی از functional boundary های سیستم نداشته باشید. زمانی که یک minimum viable product را توسعه می‌دهید، تفکیک طبیعی بین قسمت‌های مختلف برنامه کم‌کم مشاهده خواهند شد. دقت کنید که واژه minimum viable product یک واژه فنی است و به معنی حداقل محصول امکان پذیر می باشند. البته چنین شرایطی ممکن است موقت باشند. در برخی دیگر از شرایط نیز ابتدا کار خود را با یک اپلیکیشن Monolithic آغاز کرده و سپس در زمان‌های دیگر سعی می کنید که Feature ها و ویژگی های مختلف توسعه داده شده را در قالب مایکروسرویس ها بشکنید. به طور کلی در بعضی از شرایط امکان شکستن یک معماری Monolithic به چندین مایکروسرویس را دارید اما استفاده از این کار مزیت زیادی را نخواهد داشت و به همین دلیل از این کار جلوگیری خواهیم کرد.

مورد بعدی اینکه با تفکیک کردن یک اپلیکیشن به چندین Process و یا سرویس متفاوت و مجزا سربار و یاOverhead های خاصی به برنامه اضافه می شود. به عبارت دیگر با انجام این کار پیچیدگی های مختلفی در هر کدام از آنProcess ها به وجود می آید. پروتکل های ارتباطی بین آنها پیچیده تر می شود. به جای استفاده کردن از Method call های ساده این بار می بایست asynchronous communications بین سرویس ها استفاده کنید. علاوه بر این موضوع در معماری مایکروسرویسی نیاز است که اجزای تشکیل دهنده و یا building blocks های مختلفی را در مایکروسرویس ها پیاده سازی کرده و در مدیریت کردن آنها از مواردی از قبیل event bus و message resiliency و retry ها و eventual consistency و غیره استفاده کنید.

اپلیکیشن eShopOnWeb از روش معماری Monolithic بر روی یک Container تک استفاده می‌کند. این اپلیکیشن شامل یک وب اپلیکیشن تک با همان تکنیک های مربوط به MVC و Web API ها و Razor Pages ها می باشد. برای استفاده از Razor Pages می توانید از بسته ی آموزش ویدئویی Razor Pages در ASP.NET Core دیدن کنید. این اپلیکیشن از طریق Solution و با استفاده از دستور docker-compose build و یا docker-compose up اجرا خواهد شد. این دستور روند پیکربندی کردن Container برای وب اپلیکیشن را انجام می‌دهد و با استفاده از Docker file موجود در root و یا ریشه مربوط به web project اقدام به اجرا کردن Container می‌کند. کد مربوط به این اپلیکیشن را می‌توانید از روی GitHub برداشته و به صورت لوکال اجرا کنید. ضمنا در رابطه با GitHub می توانید از بسته ی آموزش ویدئویی گیت هاب (GitHub) و مبانی استفاده کردن از آن دیدن بفرمائید. حتی این اپلیکیشن Monolithic ساده نیز می تواند از مزایای استفاده کردن از Container ‌ها بهره‌مند شود.

نکته دیگر اینکه منظور از containerized deployment این است که هر instance از اپلیکیشن در یک environment‌ یکسان اجرا می‌شود. environment‌ های مختلف از قبیل developer environment‌ که روال تست کردن و یا توسعه نرم‌افزار در آن اتفاق می‌افتد مشمول این قانون هستند. در این روال تیم توسعه نرم‌افزار می‌تواند اپلیکیشن را در یک Containerized Environment که تطابق زیادی با Production Environment دارد اجرا کند.

علاوه بر این موضوع اپلیکیشن هایی که به صورت Containerized شده عمل می‌کنند روال Scale شدن ساده تر و کم هزینه تری را نیز خواهند داشت. استفاده کردن از یک Container Environment به اشتراک گذاشتن منابع و یا Resource Sharing‌ را نسبت به ماشین‌های مجازی ساده تر خواهد کرد.

و نهایتاً استفاده کردن از Containerها برای اپلیکیشن ها تفکیک مناسبی را بین business logic و سرور ذخیره سازی و یا storage server ایجاد می‌کند. به همین دلیل زمانی که برنامه نیاز به Scale شدن دارد چندین Container می توانند بر روی یک فضای ذخیره سازی فیزیکی تک لحاظ بگردند. این فضای ذخیره سازی اغلب بانک اطلاعاتی SQL Server را اجرا کرده و از قابلیت Availability و یا دسترس‌پذیری بسیار بالایی برخوردار است. در درس بعدی می‌خواهیم در رابطه با پشتیبانی از داکر موضوعات مربوط به آن صحبت کنیم.