
از لحاظ توزیع پذیری دو نوع معماری نرم افزار وجود دارد:
- Monolithic یا یکپارچه
- Microservice که به صورت توزیع شده (Distributed) عمل می کند.
تصویری از معماری یکپارچه

تصویری از معماری Micro Service ( توزیع شده)

معماری Microservice چیست؟
- مایکروسرویس روشی به منظور تقسیم بندی کردن یک نرمافزار به بخشها یا سرویسهای کوچک، سبُک، مستقل از یکدیگر و قابلمدیریت است. به عبارت دیگر، مایکروسرویس یک معماری توسعه ی نرمافزار توزیع شده (Distributed) است.
- همانطور که در تصویر معماری Micro Service مشاهده میشود، این نوع سرویسها صرفاً به منظور هندل کردن یکTask خاص طراحی میشوند.
- به طور مثال، یک سرویس صرفاً وظیفه ی مدیریت کاربران را دارا است و سرویس دیگر فقط برای بخش جستجوی سایت کاربرد دارد و با توجه به اینکه مایکروسرویسها مجزا و مستقل از یکدیگر هستند، به راحتی قادر خواهیم بود تا آنها را با زبانهای برنامهنویسی مختلفی نوشته و برای ذخیرهسازی دادههای مرتبط با آنها نیز از سیستمهای مدیریت دیتابیس مختلفی استفاده کنیم.
- جاهایی که نیاز به ذخیرهسازی سنتی دادهها داریم میتوانیم از دیتابیس های رابطه ای نظیر MySQL استفاده کنیم و جاهایی دیگر هم به خاطر ساختار غیرقابل پیشبینی دیتای خود میتوانیم به استفاده از دیتابیسهای به اصطلاح NoSQL بپردازیم.
- سرویس های مختلف با استفاده از Requestهایی از جنس HTTP و یکسری API به اصطلاح RESTful با هم ارتباط برقرار خواهند کرد.
توضیح مفاهیم
در مبحث مایکروسرویس، معمولا با اصطلاحات زیر سر و کار داریم
- JWT مخفف JSON Web Tokens می باشد.
- CQRS مخفف Command Query Responsibility Segregation می باشد. اصلی ترین ایده ی پشت این الگو جدا کردن command و query ها میباشد.
- Command دستوراتی هستند که چیزی را بر نمیگردانند و هدف اصلی آنها درج، ویرایش و حدف می باشد.
- Query دستوراتی هستند که در خروجی خود دیتا برمیگردانند و برای گرفتن اطلاعات از دیتابیس استفاده میشود.
- SOA مخفف Service Oriented Architecture می باشد.
تفاوت Micro Service با SOA
- در معماری SOA کامپوننتها یا ماژولهایی وجود دارند که سرویسهایی را در اختیار دیگر کامپوننتها قرار میدهند اما این کامپوننتها صرفا منحصر به یک اپلیکیشن خاص می باشند اما در مقابل در معماری MicroService این کامپوننتها به عنوان سرویسهای کاملاً مستقلی هستند که به صورت تکی هم میتوان آنها را Deploy کرد.
- نکته ی دیگری که در ارتباط با تفاوتهای این دو معماری نرمافزار باید مد نظر داشت، سایز ماژولها است. به عبارت دیگر، مایکـروسرویـس ها به مراتب کوچـک ترند و همین مسـئله مدیریت آنها را به مراتـب سـادهتر میسازد.
- مایکروسرویس نسبت به معماری مبتنی بر سرویس انعطافپذیرتر است چرا که به سادگی میتوان یک سرویس یا ماژول را از پروژهای برداشت و بدون پیکرهبندی خاصی آن را در پروژه ی دیگری استفاده کرد اما این در حالی است که معماری SOA داخل یک معماری اصطلاحاً Monolithic پیادهسازی میشود.
مزایای مایکروسرویس ها
- بر خلاف معماری مونولیتیک، در یک اپلیکیشنی که در آن از معماری مایکروسرویس استفاده شده باشد سرویسها هرگز بر اساس معماری MVC تقسیمبندی نمیشوند بلکه بر اساس کاری که انجام میدهند به بخشهای مختلف تقسیم میشوند. به عبارت دیگر، یک سرویس همچون آپلود فایل شامل بخشهایی همچون رابط کاربری، مدلهای مرتبط با دیتابیس، کنترلر، سیستم لاگینگ و … خواهد بود (در چنین شرایطی، فرض کنیم دولوپر سرویسی تحت عنوان File Uploader میسازد و از آن پس به سادگی قادر خواهد بود سرویس مد نظر را در دیگر پروژهها که کاربرد یکسانی دارند نیز استفاده کند.)
- یکی دیگر از مزیتهای مایکروسرویسها این است که ما مجبور به استفاده از صرفاً یک زبان برنامهنویسی یا فناوری در کل پروژه نمیشویم. در واقع، با توجه به اینکه امروزه برخی زبانهای برنامهنویسی برای حوزههای خاصی تخصصیتر هستند و استفاده از زبانی که اختصاصاً برای کار خاصی طراحی شده کارایی اپلیکیشن ما را بالاتر میبرد، با استفاده از مایکروسرویسها قادر خواهیم بود تا بسته به نوع سرویس مد نظر خود از چندین زبان برنامهنویسی و فناوری مختلف استفاده کرده و کارایی را به بالاترین حد خود برسانیم.
- علاوه بر موارد فوق، مایکروسرویسها اصطلاحاً Scalable (قابلتوسعه) هستند. ماهیت مستقل ماژولهای مختلف یک مایکروسرویس این امکان را فراهم می سازد تا با استفاده از زبانی خاص، دیتابیسی خاص و همچنین سروری خاص به توسعه ی اپلکیکشن مد نظر خود بپردازیم و در صورت نیاز صرفاً منابع همان پلتفرم را ارتقاء دهیم.
معایب مایکروسرویسها
- از آنجا که هر سرویس مسئول انجام Task خاصی است، در اپلیکیشنهای بسیار بزرگ تعداد سرویسهای بیشماری خواهیم داشت و از همین روی برقراری ارتباط مابین این سرویسها و از همه مهمتر مانیتور کردن آنها کاری بس دشوار خواهد بود (برخی دادهها حاکی از آنند که سرویسی همچون Netflix صدها سرویس مختلف دارد.)
- با توجه به اینکه سرویسها برای برطرف کردن نیازهای خود دیگر سرویسها را فراخوانی میکنند، رصد کردن آنها و مخصوصا فرایند Debugging بسیار دشوار خواهد شد.
- هر سرویس لاگگیری اختصاصی خود را دارا است و از همین روی هیچ سیستم مانیتورینگ مرکزی برای بررسی لاگها وجود ندارد و در چنین شرایطی نیاز به یک سیستم مدیریت لاگ مرکزی وجود خواهد داشت.
- با توجه به اینکه ارتباط سرویسها با یکدیگر از طریق API است، تعداد Requestها نسبت به یک معماری مونولیتیک به مراتب بیشتر خواهد بود.
- Deploy کردن اپلیکیشنهایی که با استفاده از معماری مایکروسرویس طراحی شدهاند به صورت دستی مشکل است و در چنین شرایطی نیاز به ابزارهای اتوماسیون پیشرفته خواهد بود.
- ورژنبندی مایکروسرویسها باید به صورت مجزا از یکدیگر صورت گیرد و اینجا است که نیاز داریم تا مشخص کنیم به طور مثال کدام ورژن سرویس A با کدام ورژن سرویس Z باید Deploy شود.
- مستنداتسازی چنین اپلیکیشنهایی مشکلتر است چرا که با توجه به ماهیت مستقل هر ماژول، سرویسها باید به صورت کامل مستندسازی شوند.
- با توجه به اینکه ممکن است از چندین زبان برنامهنویسی و تکنولوژی مختلف در چنین اپلیکیشنهایی استفاده شود، هزینه ی نگهداری چنین سیستمها گاهی اوقات زیاد میشود به طوری که مثلاً نیاز به استخدام Developer زبانهای مختلف خواهیم داشت.
- امروزه اکثر اپلیکیشنها نیاز دارند تا در آنِ واحد چندین رکورد را در دیتابیس حذف یا بهروزرسانی کنند. در چنین مواقعی با توجه به اینکه در معماری مونولیتیک صرفاً یک دیتابیس وجود دارد، اینکار به سادگی صورت خواهد گرفت اما در مایکروسرویسها چنین حذف یا بهروزرسانیهایی چالشی خواهند شد چرا که ممکن است رکوردی در دیتابیس یکی از سرویسها در یک سرور خاص به همراه رکورد دیگری در سرویس دیگری روی سرور دیگری بخواهند با یکدیگر سینک شوند.
چه زمانی به مایکروسرویس مهاجرت کنیم؟
- چنانچه سورسکد پروژه آنقدر حجیم شده است که توسعه ی آن به صورت لوکال، مثلاً لود کردن کل پروژه داخل یک IDE، کار دشواری شده است و نیاز به توضیح نیست که فرایند Build کردن برخی از پروژههای بسیار بزرگ که به صورت مونولیتیک نوشته شدهاند گاهی دهها دقیقه به طول میانجامد.
- صرفاً برخی بخشهای اپلیکیشن نیاز به توسعه دارند و این در حالی است که در معماری مونولیتیک شما باید به یک باره کل منابع سیستمی خود را ارتقاء دهید و این در صورتی است که ممکن است اصلاً نیاز به ارتقاء به این شکل نباشد.
- چنانچه توسعه دهنده ها در کنار یکدیگر نیستند و نمیتوانند به صورت مستقل از یکدیگر روی پروژه کار کنند.
CQRS چیست؟

فرض کنید که در حال طراحی یک سیستم فروشگاهی هستید. در این نوع سیستم به دلیل ساختار رابطه ای سیستم بهترین روش برای ذخیره سازی داده استفاده از دیتابیس های رابطه ای مانند SQL Server ، MySql میباشد. همچنین در هنگام واکشی اطلاعات به دلیل خاصیت های زیادی که هر محصول میتواند داشته باشد و بزرگ بودن آبجکت مورد نیاز بهترین راه حل استفاده از دیتابیسهای No SQL مثل Mongo Db میباشد.
با این شرایط راه حل چیست؟؟
در چنین پروژه ای باید از الگوی CQRS استفاده کرد. در این سیستم فروشگاهی لایه ی Repository را به دو بخش کلی تقسیم میکنیم که یه بخش شامل Command ها و بخش دیگر شامل Query ها میباشد که تمامی متد ها را بر اساس نوع آنها جدا میکند.
زمانی که اطلاعات در دیتابیس رابطه ای درج، ویرایـش یا حذف می شود یک سرویس که اصطلاحا به آن Service Bus میگویند داده های درج شده در دیتابیس رابطه ای را پردازش میکند و آبجکت پیچیده ای که زمان واکشی داده نیاز داریم را به صورت آماده در دیتابیس NoSql ذخیره میکند. در این حالت در زمان واکشی داده برای دریافت داده نیاز به دستورات سخت و پیچیده نیست، همچنین سرعت واکشی داده به دلیل از پیش پردازش شدن به شدت کاهش میابد.
باز هم توجه داشته باشید که پیچیدگی های CQRS به حدی بالاست که اصلا عاقلانه نیست که برای هر پروژه ای از آن استفاده کنید و نیاز است در استفاده از آن به نیاز سیستم خود اشراف کامل داشته باشید.