میکروسرویس (Microservice) چیست؟

میکروسرویس (Microservice) چیست؟

امروزه با نیاز رو به رشدی که به اپلیکیشن‌های اینترپرایز (تجاری) به وجود آمده است، مفهومی تحت عنوان Microservice هم در میان دولوپرها رواج یافته است چرا که ایشان برای توسعهٔ سیستم‌های بزرگ اینترپرایز، چاره‌ای جز به‌کارگیری از معماری میکروسرویس ندارند. در ظاهر مفهوم میکروسرویس کمی پیچیده به نظر می‌رسد اما در واقعیت هرگز این‌گونه نیست و در این پست قصد داریم چیستی، چرایی و همچنین مزایا و معایب به‌کارگیری از میکروسرویس‌ها را مورد بررسی قرار دهیم.

به طور کلی، در سال‌های اخیر استفاده از واژهٔ Microservice در میان دولوپرها به کرات دیده می‌شود؛ برخی از ایشان از این اصلاح به منظور تشریح معماری اپلیکیشن خود استفاده می‌کنند و برخی دیگر هم به خاطر مُد روز بودن این اصطلاح گاهی‌اوقات آن را به زبان می‌آورند!

اما آنچه مسلم است اینکه برای یک دولوپر، آشنایی با ماهیت میکروسرویس‌ها یک باید است چرا که به دلیل کاربردی بودن و بهینگی این نوع معماری در توسعهٔ نرم‌افزاری بزرگ و پیچیده، به نظر می‌رسد که آیندهٔ توسعهٔ اپلکیشن‌ها -از هر نوعی- وابسته به میکروسرویس‌ها باشد.

معماری Monolithic چیست؟
برای درک ماهیت میکروسرویس‌ها، ابتدا بایستی ببینیم که معماری اصطلاحاً Monolithic چگونه کار می‌کند. به طور کلی، در این نوع معماری ما سه لایه داریم تحت عناوین:
Model (منطق اپلیکیشن)
- View (خروجی اپلیکیشن)
- Controller (رابط مابین خروجی و منطق اپلیکیشن)

برای روشن‌تر شدن این مسئله، مثالی می‌زنیم. فرض کنیم کاربری از طریق گوگل کروم یا فایرفاکس وارد سکان آکادمی می‌شود. به محض اینکه وارد هوم‌پیج می‌شود، یک ریکوئست (درخواست) برای سرور سکان آکادمی ارسال می‌گردد که لایهٔ مرتبط با Controller این درخواست را گرفته و برای لایهٔ Model ارسال می‌کند و این لایه هم با دیتابیس ارتباط برقرار ساخته و دیتای مرتبط با هوم‌پیج را فراخوانی کرده و در صورت نیاز یکسری کارها برای تر و تمیز کردن داده‌ها انجام داده و در نهایت مجدد در اختیار Controller قرار می‌دهد و Controller هم دیتای موجود را در اختیار View قرار می‌دهد و این لایه هم خروجی هوم‌پیج سکان آکادمی را داخل مرورگر کاربر نشان می‌دهد.

مشکلات مرتبط با معماری Monolithic
این نوع معماری که تحت عنوان معماری MVC هم شناخته می‌شود دارای یکسری نواقصی است. به عبارت دیگر، تمامی لایه‌ها (مدل، ویو و کنترلر) زیر پرچم یک پلتفرم واحد مدیریت می‌شوند و ارتباط بسیار تنگاتنگی با یکدیگر دارند و مثلاً به سادگی نمی‌توان Model یک اپلیکیشنی که تحت معماری MVC نوشته شده را برداشته و در پروژهٔ دیگری استفاده کرد.

 میکروسرویس (Microservice) چیست؟

همان‌طور که در تصویر فوق مشخص است، در معماری Monolithic یک هستهٔ مرکزی داریم که کاربران، دیگر سرویس‌ها و غیره از طرق مختلف می‌توانند با آن ارتباط برقرار سازند. همان‌طور که می‌بینیم، اگرچه که خود این هستهٔ مرکزی ماژولار (بخش‌بندی) است، اما همگی تحت یک پلتفرم واحد کنار یکدیگر قرار گرفته‌اند و امکان مجزاسازی این ماژول وجود ندارد و یا اگر هم چنین امکانی وجود داشته باشد، بسیار دشوار خواهد بود.

اگرچه که در معماری MVC کدها ماژولار هستند و نسبت به گذشته که تمامی فایل‌ها در یک پوشه گذاشته می‌شدند و اصلاً مفهومی تحت عنوان ماژول در کار نبود شرایط به مراتب بهتر است، اما همان‌طور که گفته شد، هر ماژول برای کارکرد صحیح و اصولی خود نیاز به سایر ماژول‌ها دارد. به طور کلی، مشکلات مرتبط با معماری Monolithic را می‌توان به دسته‌های زیر تقسیم‌بندی کرد:

- از آنجا که یک سورس‌کد اصلی بیشتر وجود ندارد، تک‌تک اعضای تیم -از دولوپر فرانت‌اند گرفته تا بک‌اند کاران و غیره- می‌بایست روی یک سورس‌کد کار کنند و به طور مثال اگر کسی بخواهد صرفاً روی بخش مدیریت کاربران کار کند، می‌بایست کل پروژه را دریافت کرده، یک هاست لوکال پیکره‌بندی کرده و شروع به کار روی پروژه کند.

- یک تغییر کوچک در یکی از ماژول‌ها، ممکن است عملکرد دیگر ماژول‌ها را تحت‌تأثیر خود قرار دهد.

- درست است که در این نوع معماری ما مفهومی داریم تحت عنوان MVC،‌ اما در طول زمان این سه لایه آن‌قدر با یکدیگر عجین خواهند شد که به سختی می‌توان مرز مشخصی مابین آنها ایجاد کرد.

- مشکل دیگری که در این نوع معماری به چشم می‌خورد این است که همان‌طور که اپلیکیشن به سه لایهٔ مختلف تقسیم‌بندی می‌شود، تیم توسعهٔ نرم‌افزار هم به سه لایهٔ مجزا از یکدیگر تقسیم‌بندی می‌شود؛ به عبارت دیگر، تیم دولوپرهای فرانت‌اند برای کار روی رابط کاربری نرم‌افزار،‌ تیم دولوپرهای دیتابیس برای کار روی ماژول‌های مرتبط با دیتابیس و تیم دولوپرهای بک‌اند برای کار با منطق کلی اپلیکیشن. در چنین شرایطی، معمولاً دولوپرها کمتر از کار یکدیگر سر در خواهند آورد و چنانچه اپلیکیشن هم به مشکلی برخورد کند، تشخیص اینکه مشکل از کدام تیم است هم ممکن است مشکل باشد.

- کامپوننت‌ها را به سادگی نمی‌توان با یک معماری جدیدتر و بهینه‌تر جایگزین کرد چرا که کل معماری نرم‌افزار دستخوش تغییر باید گردد.

- تنوع تکنولوژی -من‌جمله زبان‌های برنامه‌نویسی، دیتابیس‌های مختلف، لایبرری‌ها و فریمورک‌های مختلف- وجود نخواهد داشت و اگر هم این‌گونه باشید، ارتباط برقرار کردن مابین آنها بسیار دشوار خواهد بود.

- یک باگ در یکی از ماژول‌ها، به احتمال زیاد کل پروژه را تحت‌الشعاع خود قرار خواهد داد.

اینجا است که پای میکروسرویس‌ها به میان می‌آید و کمپانی‌های بزرگی همچون آمازون یا نتفلیکس به استفاده از میکروسرویس‌ها روی آورده‌اند.

معماری Microservice چیست؟
میکروسرویس‌ روشی به منظور تقسیم‌بندی کردن یک اپلیکیشن (در اینجا منظور اپ موبایل نیست بلکه هر نوع نرم‌افزاری را شامل می‌گردد) به بخش‌ها یا سرویس‌های کوچک، سبک، مستقل و قابل مدیریت است. به عبارت دیگر، میکروسرویس یک معماری توسعهٔ‌ نرم‌افزار Distributed (پخش‌شده) است.

 میکروسرویس (Microservice) چیست؟

همان‌طور که در تصویر فوق مشاهده می‌شود، این نوع سرویس‌ها صرفاً به منظور هندل کردن یک تَسک خاص طراحی می‌شوند؛ به طور مثال، یک سرویس صرفاً وظیفهٔ مدیریت کاربران را دارا است و سرویس دیگر فقط و فقط برای بخش جستجوی سایت کاربرد دارد.

باتوجه به اینکه میکروسرویس‌ها مجزا و مستقل از یکدیگر هستند، به راحتی قادر خواهیم بود تا آنها را با زبان‌های برنامه‌نویسی مختلفی نوشته و برای ذخیره‌سازی داده‌های مرتبط با آنها، از سیستم‌های مدیریت دیتابیس مختلفی استفاده کنیم (به عبارت دیگر، جاهایی که نیاز به ذخیره‌سازی سنتی داده‌ها داریم می‌توانیم از MySQL استفاده کنیم و جاهایی دیگر هم به خاطر ساختار غیرقابل پیش‌بینی دیتای خود، می‌توانیم به استفاده از دیتابیس‌های به اصطلاح NoSQL بپردازیم).

حال ممکن است این سؤال پیش بیاید که سرویس‌های مختلف یک اپلیکیشن با معماری میکروسرویسی چگونه با یکدیگر ارتباط برقرار می‌کنند؟ در پاسخ به این سؤال بایستی گفت که -همان‌طور که در تصویر فوق مشخص است- با استفاده از ریکوئست‌هایی از جنس HTTP و APIهای به اصطلاح RESTful این ارتباط برقرار خواهد شد.

آشنایی با معماری Service Oriented Architecture
اینجا سؤال دیگری به ذهن می‌رسد و آن هم اینکه با این تفاسیر تفاوت چندانی مابین SOA با Microservice وجود ندارد (SOA مخفف واژگان Service Oriented Architecture است). در پاسخ به این سؤال هم بایستی گفت که Microservice نوعی SOA است که طی ده‌های گذشته خیلی مطرح بوده است. با این حال، Microservice نسبت به SOA (معماری سرویس‌گرا) انعطاف‌پذیرتر است چرا که به سادگی می‌توان یک سرویس یا ماژول را از پروژه‌ای برداشت و بدون پیکره‌بندی خاصی آن را در پروژه‌ٔ دیگری استفاده کرد اما این در حالی است که معماری SOA داخل یک معماری اصطلاحاً Monolithic پیاده‌سازی می‌شود.

به عبارت دیگر، در معماری SOA ما کامپوننت‌هایی (ماژول‌هایی) داریم که سرویس‌هایی را در اختیار دیگر کامپوننت‌های قرار می‌دهند و این در حالی است که این کامپوننت‌ها می‌توانند منحصر به یک اپلیکیشن خاص باشند اما در نقطهٔ مقابل، در معماری یک Microservice این کامپوننت‌ها به عنوان سرویس‌های کاملاً مستقلی هستند که به صورت تکی هم می‌توان آنها را دیپلوی کرد. نکتهٔ دیگری که در ارتباط با تفاوت‌های SOA و Microservice باید مد نظر داشت، سایز است. به عبارت دیگر، میکروسرویس‌ها به مراتب کوچکترند و همین مسئله مدیریت آنها را به مراتب ساده‌تر می‌سازد.

برای درک بهتر تفاوت‌های مابین معماری‌های Microservice ،Monolithic و SOA می‌توان اولین تصویری که در این مقاله استفاده شده را مد نظر قرار داد. در واقع از چپ به راست، معماری‌های SOA ،Monolithic و Microservice در قالب خوراکی به تصویر کشیده‌ شده‌اند. 

در تصویر سمت چپ می‌بینیم که معماری -Monolithic- به گونه‌ای است که ارتباط تنگاتنگی مابین ماژول‌های مختلف اپلیکیشن وجود دارد (اصطلاحاً Tightly Coupled است) و در صورتی که بخواهیم تغییری در یکی از بخش‌ها دهیم، با مشکل مواجه خواهیم شد و همین مسئله CD را دشوار می‌سازد (CD مخفف واژگان Continous Deployment است).

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

در تصویر سمت راست که معماری Microservice نشان داده شده است،‌ برخلاف دو معماری دیگر می‌بینیم که هر ماژول کاملاً مستقل از دیگر ماژول‌ها است (اصطلاحاً Loosely Coupled است) و همچون یک پیراشکی، می‌توان آن را به تنهایی میل کرد!

مزایای استفاده از میکروسرویس‌ها
امروزه ماژولار (قطعه قطعه بودن) به یک مزیت رقابتی در هر صنعتی مبدل شده است. از مبلمان IKEA بگیریم تا گوشی‌های موبایل ماژولار و حتی اسباب‌بازی‌های LEGO. به طور کلی، ایدهٔ پشت میکروسرویس‌ها این است که این امکان به دولوپرها داده شود تا اپلیکیشن‌های خود را از اجزا یا سرویس‌هایی که مستقل از یکدیگر هستند و به سادگی قابل تغییر، حذف و به‌روزرسانی می‌باشند ایجاد کنند بدون اینکه کل اپلیکیشن تحت‌الشعاع قرار گیرد (این در حالی است که در معماری به اصطلاح Monolithic اصلاً این‌گونه نیست). مهم‌ترین مزایای استفاده از میکروسرویس‌ها عبارتند از:

- بر خلاف معماری Monolithic، یک اپلیکیشن که در آن از معماری میکروسرویس استفاده شده باشد، میکروسرویس‌هایش هرگز بر اساس لایهٔ نرم‌افزاری (MVC) تقسیم‌بندی نمی‌شوند بلکه بر اساس کاری که انجام می‌دهند به بخش‌های مختلف تقسیم می‌شوند. به عبارت دیگر، یک سرویس -همچون آپلود فایل- شامل رابط کاربری، مدل‌های مرتبط با دیتابیس، کنترلر، سیستم لاگینگ و ... خواهد بود (در چنین شرایطی، فرض کنیم دولوپر سرویسی تحت عنوان File Uploader می‌سازد. از آن پس، به سادگی قادر خواهد بود سرویس مد نظر را در دیگر پروژه‌ها که کاربرد یکسانی دارند نیز استفاده کند).

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

- علاوه بر موارد فوق، میکروسرویس‌ها اصطلاحاً Scalable (قابل توسعه) هستند. ماهیت مستقل سرویس‌های یک میکروسرویس، این امکان را برایمان فراهم می‌آورند تا با استفاده از زبانی خاص، دیتابیسی خاص و همچنین سروری خاص به توسعهٔ اپلکیکشن مد نظر خود بپردازیم و در صورت نیاز، صرفاً منابع همان پلتفرم را ارتقاء دهیم.

معایب استفاده از میکروسرویس‌ها
تا اینجای بحث از خوبی‌ها میکروسرویس‌ها گفتیم اما بایستی توجه داشته باشیم که این نوع معماری توسعهٔ اپلیکیشن نقاط منفی خاص خود را هم دارا است که در ادامه به برخی از مهم‌ترین آنها اشاره‌ای خواهیم کرد:

- از آنجا که هر سرویس مسئول انجام Function (وظیفهٔ) خاصی است، در اپلیکیشن‌ها بسیار بزرگ ما تعداد سرویس‌های بی‌شماری خواهیم داشت و از همین روی، برقراری ارتباط مابین این سرویس‌ها و از همه مهم‌تر مانیتور کردن آنها کاری بس دشوار خواهد بود (برخی داده‌ها حاکی از آنند که سرویسی همچون نتفلیکسن بیش از ۶۰۰ سرویس مختلف دارد).

- باتوجه به اینکه سرویس‌ها برای برطرف کردن نیازهای خود، دیگر سرویس‌ها را فراخوانی می‌کنند، رصد کردن آنها و بالتبع فرایند دیباگینگ بسیار دشوار خواهد شد.

- هر سرویس لاگینگ اختصاصی خود را دارا است؛ لذا هیچ سیستم مانیتورینگ مرکزی برای بررسی لاگ‌ها وجود ندارد و در چنین شرایطی نیاز به یک سیستم مدیریت لاگ حرفه‌ای وجود خواهد داشت.

- باتوجه به اینکه ارتباط سرویس‌ها با یکدیگر از طریق API است، تعداد رکوئست‌ها نسبت به یک معاری Monolithic به مراتب بیشتر خواهد بود. 

- دیپلوی کردن اپلیکیشن‌هایی که با استفاده از معماری میکروسرویس طراحی شده‌اند به صورت دستی مشکل است و در چنین شرایطی نیاز به ابزارهای اتوماسیون پیشرفته خواهد بود.

- ورژن‌بندی میکروسرویس‌ها بایستی به صورت مجزا از یکدیگر صورت گیرد و اینجا است که بایستی مشخص کرد به طور مثال کدام ورژن سرویس A با کدام ورژن سرویس Z بایستی دیپلوی شوند.

- مستندات‌سازی چنین اپلیکیشن‌هایی مشکل‌تر است چرا که باتوجه به ماهیت مستقل هر سرویس، سرویس‌ها بایستی به صورت کاملا مستندسازی شوند.

- باتوجه به اینکه ممکن است از چندین زبان‌ برنامه‌نویسی و تکنولوژی مختلف در چنین اپلیکیشن‌هایی استفاده شود، هزینهٔ نگهداری چنین سیستم‌ها گاهی‌اوقات زیاد می‌شود (مثلاً نیاز به استخدام دولوپر زبان‌های مختلف خواهیم داشت).

- امروزه اکثر اپلیکیشن‌ها نیاز دارند تا در آن واحد چندین رکورد را در دیتابیس حذف یا به‌روزرسانی کنند. در چنین مواقعی باتوجه به اینکه در معماری Monolithic صرفاً یک دیتابیس وجود دارد، اینکار به سادگی صورت خواهد گرفت اما در میکروسرویس‌ها چنین حذف یا به‌روزرسانی‌هایی چالشی خواهند شد چرا که ممکن است رکوردی در دیتابیس یکی از سرویس‌ها در یک سرور خاص به همراه رکورد دیگری در سرویس‌ دیگری روی سرور دیگری بخواهند با یکدیگر آپدیت شوند.

چه زمانی به میکروسرویس مهاجرت کنیم؟
آنچه در ادامه خواهیم آورد، شرایطی است که اگر در مورد شما صدق می‌کنند زمان آن فراهیم رسیده که میکروسرویس هم جزو یکی از گزینه‌های پیش‌ روی شما باشد:

- چنانچه سورس‌کد پروژه‌ٔ شما آن‌قدر حجیم شده است که توسعهٔ آن به صورت لوکال -مثلاً لود کردن کل پروژه داخل یک IDE- کار دشواری شده است (فرایند ‌Build برخی از پروژه‌های بسیار بزرگ که به صورت Monolithic نوشته شده‌اند از ۱۰ دقیقه تا ۴۰ دقیقه به طول می‌انجامد).

- صرفاً برخی بخش‌های اپلکیشن نیاز به توسعه دارند و این در حالی است که در معماری Monolithic شما می‌بایست به یک باره کل منابع سیستمی خود را ارتقاء دهید و این در صورتی است که ممکن است اصلاً نیاز به ارتقاء به این شکل نباشد.

- چنانچه دولوپرها در کنار یکدیگر نیستند و نمی‌توانند به صورت مستقل از یکدیگر روی پروژه کار کنند

نتیجه‌گیری
مبحث معماری میکروسرویس بسیار گسترده است و زمانی که بخواهیم وارد این حوزه شویم، می‌بایست با مفاهیمی همچون Continuous Integration ،‌Continuous Deploymnet ،Docker و همچنین ابزارهای دیپلوی خودکار نیز آشنا شویم اما آشنایی در همین حدی که در این پست صورت گرفت، برای هر دولوپری فارغ از اینکه بخواهد وارد این حوزه شود یا خیر، ضروری است.

حال نوبت به نظرات شما می‌رسد. آیا تجربهٔ کار با معماری Microservice را داشته‌اید؟ به نظر شما مزایا و معیاب این نوع معماری چیست؟ نظرات، دیدگاه‌ها و تجربیات خود را با ما و سایر کاربران سکان آکادمی به اشتراک بگذارید.