sina mohammadi
sina mohammadi
خواندن ۲۶ دقیقه·۱۰ ماه پیش

بررسی معماریھای مبتنی بر میکروسرویس و کانتینرها

مقدمه

در این مطلب تلاش شده به سوالاتی در خصوص معماری میکروسرویس پاسخ داده شود. این سوالات بعضا از جنس معماری و بعضا برسی ابزار های مختلف که به پیاده سازی این معماری کمک میکند هستند.

در بخش اول ابتدا تعریفی از معماری میکروسرویس ارائه میشود. سپس به برسی تفاوت های معماری میکروسرویس و monolithic پرداخته میشود همچنین نقاط قوت و ضعف هرکدام برسی شده و اصولی برای مهاجرت از معماری monolithic به میکروسرویس ارائه میشود.

در بخش بعدی به برسی اصولی پرداخته می شود که رعایت آن در معماری میکروسرویس باعث بهبود برخی از شاخص های کیفی معماری نرم افزار میشود.

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

بخش آخر به برسی ابزار ها و نکات مهم در فرآیند دیپلویمنت مرتبط به این معماری پرداخته میشود و برخی از این ابزار ها با هم مقایسه میشوند.

تاریخچه معماری میکروسرویس

نیاز به وجود نرم افزاری که اجزای آن به صورت کاملا مستقل قابل قابل استقرار باشند در بین سال های ۱۹۹۰ تا ۲۰۰۰ برای حس شد.ابتدا این مشکل توسط معماری سرویس محور در همان سال ها برطرف شد. به این صورت که ماژول های مختلف که وابستگی کمی از هم داشتند به صورت مستقل از هم استقرار میافتند.

در آن سال ها استاندارد ارتباط سرویس ها با هم از طریق پروتکل پیامرسانی SOAP انجام میشد. ولی بین سال های ۲۰۰۸ تا ۲۰۱۰ استاندارد REST معرفی شد که از طریق پروتکل HTTP پیام رسانی را انجام میداد و این موضوع باعث راحتی ارتباط بین سرویس های مختلف شد.

تولد معماری میکروسرویس بین سال های ۲۰۱۱ تا ۲۰۱۲ اتفاق افتاد زمانی که گروهی متشکل از James Lewis و Martin Fowler یک معماری را طراحی کردند که در آن سرویس های تا حد زیادی کوچک توسط یک سیستم پیام رسانی سبک مانند api های در بستر HTTP با هم ارتباط داشتند.


معماری میکروسرویس چیست؟

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

این ارتباط معمولا از طریق API ها یا message broker ها انجام میشود که در فصل پنجم بیشتر به این موضوع پرداخته میشود.


یکپارچگی و دوگانگی در میکروسرویس ها

در طراحی این معماری لازم است دو نکته مهم مدنظر قرار بگیرد:

۱) یکپارچگی: اجزای یک سرویس (ماژول ها، کلاس ها و …) لازم است که کاملا یکپارچه باشند. به عنوان مثال اگر سرویسی شامل دو ماژول است که با هم هیچ ارتباطی ندارند این دو ماژول میتوانند به دو سرویس مجزا تقسیم شوند.

۲) دوگانگی: در صورتی که دو سرویس به هم وابسته باشند اگر یکی از این سرویس ها تغییر کرد سرویس دیگر هم لازم است که تغییر کند. پس ارتباط بین سرویس ها باید تا حد ممکن کم باشد و تنها در موارد ضروری این ارتباط ایجاد شود.

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


یک مثال عملی - معماری نرم افزار spotify

اسپاتیفای یک نرم افزار استریم موسیقی میباشد. میلیون ها کاربر به طور همزمان از این نرم افزار برای شنیدن موسیقی استفاده میکنند. پس لازم است که زیرساخت لازم برای مدیریت حجم بالای درخواست ها را داشته باشد.

برای مدیریت بیشتر این نرم افزار از معماری میکروسرویس استفاده میکند که در اینجا به نحوه پیاده سازی این معماری در نرم افزار اسپاتیفای میپردازیم.

تعدادی از نیازمندی های این نرم افزار

  • این نرم افزار باید قابلیت سرویس دهی به میلیون ها کاربر را داشته باشد.
  • این نرم افزار باید در پلتفرم های متفاوت مثل گوشی های موبایل ، سیستم عامل های مختلف و … قابل استفاده باشد.
  • این نرم افزار باید قوانین پیچیده کسب و کاری را پیاده سازی کند.
  • این نرم افزار باید بتواند قابلیت های جدید را به سرعت اضافه کند.

یک نکته مهم در مورد این نرم افزار این است که بر خلاف بیشتر نرم افزار ها که کاربران ساعات کمی را در آن صرف میکندد در این نرم افزار ممکن ساعت های زیادی گاها تا ۸ ساعت در روز را صرف کنند. در این صورت تنها مشکل تعداد بالای کاربران نیستند بلکه ساعت بالای استفاده هم یکی از مشکلات و نیازمندی های این نرم افزار است.

راه حل

برای برطرف کردن این نیازمندی ها این نرم افزار اجزای مختلف را به قسمت های کوچک تر تقسیم کرده و این تقسیم حتی در سطح تیم ها نیز اعمال شده به این شکل که هر تیم مسئول بخش کوچکی از نیازمندی ها میباشد. هر تیم شامل توسعه دهنده های فرانت اند و بک اند ، نیروی تست و … میباشد. این مدل از تقسیم بندی باعث میشود که هر تیم کاملا مستقل بوده ، آزادانه کار کند و به تیم های دیگر وابسته نباشد.

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

خدماتی که پلتفرم اسپاتیفای ارائه میدهد به هفت دسته بندی تقسیم میشوند از جمله‌:

  • یافتن موسیقی و پیشنهاد موسیقی به کاربران
  • مدیریت لیست پخش
  • ویژگی هایی مانند شبکه های اجتماعی (اشتراک گذاری لیست پخش)
  • احراز هویت و امنیت کاربران
  • مدیریت داده ها
  • مدیریت زیر ساخت ها

برای پیاده سازی این زیرساخت ها اسپاتیفای از تعداد زیادی سرویس های کوچک استفاده میکند. در نوامبر ۲۰۲۳ اسپاتیفای دارای ۱۶۰۰ سرویس مختلف بوده است. همچنین به طور متوسط هر ماه حدودا ۱۰۰ سرویس جدید به این تعداد افزوده میشود.


نقاط قوت معماری میکروسرویس

  1. این معماری روند توسعه نرم افزار را سریع تر و آسان تر میکند. از آنجایی که هر سرویس به صورت مجزا توسعه داده میشود پس تیم هایی که وظیفه توسعه این سرویس ها را دارند تنها کافی است نگران کارکرد درست سرویس مورد نظر باشند و نیاز نیست که کارکرد صحیح کل سیستم را برسی کنند.
  2. از آنجایی که این در این معماری هر سرویس به صورت مجزا دیپلوی و نگهداری میشود. پس availability بالایی را میتوان از این معماری انتظار داشت. زیرا در صورت از کار افتادن یک سرویس ، بقیه سرویس ها بدون مشکل کار میکنند، همچنین فرآیند شناسایی خطا ، مانیتورینگ و برطرف کردن مشکل در این معماری راحت تر است.
  3. هر سرویس در این معماری میتواند به صورت مجزا استقرار پیدا کرده و اجرا شود. در این صورت با افزایش تعداد کاربران به راحتی میتوان سرویس هایی که مشکل پرفرمنس دارند را شناسایی و مشکلشان را برطرف کرد.

نقاط ضعف معماری میکروسرویس

  1. اولین مشکل این معماری مشکل پرفرمنس است. از آنجایی که در این معماری سرویس ها با یک واسط مانند REST api یا صف ها با هم در ارتباط هستند، این ارتباط بار بیشتری در حالتی که ماژول ها به صورت programmatically هم دیگر را صدا میزنند روی سیستم میگذارد می گذارد.
  2. مشکل بعدی مشکل وابستگی سرویس ها به یکدیگر است. در تعریف میکروسرویس ذکر شد که سرویس ها باید تا جای ممکن از هم مستقل باشند، ولی این استقلال در عمل تا حد زیادی امری محال است. سرویس های مختلف برای انجام عملیات خود به دیتاها و عملیات هایی از سرویس های دیگر وابسته هستند و اگر این ارتباط از حدی بیشتر شود مشکل پروفرمنیس رخ میدهد. همچنین در صورت از کار افتادن سرویسی که سرویس های دیگر به آن وابسته هستند، سرویس های وابسته نیز از کار می افتند.
  3. نرم افزار پیاده سازی شده با معماری میکروسرویس به منابع سخت افزاری بیشتری نسبت به معماری های دیگر نیاز دارد زیرا هر سرویس به صورت مجزا اجرا شده و نبازمندی های خود را دارند. همچنین ارتباط این سرویس ها با هم بار مضاعف روی سخت افزار میگذارد.
  4. در طراحی ماکروسرویس ها، طراحان معمولا تاخیر و قطعی شبکه را صفر در نظر میگیرند. در حالی که در یک شبکه کامپیوتری هرچقدر که شبکه پایدار و مطمئن باشد باز هم امکان قطعی یا کاهش پهنای باند وجود دارد. در این صورت سرویس ها نمیتوانند به درستی با هم ارتباط داشته باشند و سیستم دچار اختلال میشود.

انواع مختلف الگو های طراحی بر پایه معماری میکروسرویس

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

  • Back-end for front-end
    • در معماری میکروسرویس client (نرم افزار فرانت اند یا اپ موبایل و …) نیاز دارد تا با تعداد زیادی از سرویس ها در ارتباط باشد. این ارتباط باعث پیچیدگی و سختی کار این client ها میشود از این رو برای حل این مشکل یک سرویس واسط پیاده سازی میشود که به آن back-end for front-end یا BFF میگویند. این سرویس از طرفی با دیگر سرویس ها در ارتباط است و از طرف دیگر برخی از دیتاهای مورد نیاز client که احتیاج به عملیات خاصی ندارند و فقط یک عملیات CRUD ساده روی دیتابیس است را انجام میدهد. و عملیات های پیچیده تر را به سرویس های دیگر میسپارد.
  • Circuit Breaker
    • در پیاده سازی نرم افزار با معماری میکروسرویس بسیار ممکن است که یک سرویس به دلیل مشکلات داخلی یا خارجی از سرویس دهی و پاسخگویی به درخواست ها باز بماند. در این صورت هر درخواست جدید که به این سرویس برسد یک بار اضافی روی منایع ایجاد کرده در حالی که بدیهی است جوابی دریافت نمیکند. در این روش وقتی تعداد درخواست های با خطا مواجه شده در یک سرویس زیاد میشود این سرویس از مدار خارج شده و هیچ درخواستی تا یک مدت مشخص به آن ارسال نمیشود. بعد از طی زمان یک درخواست تستی به سرویس ارسال شده اگر سرویس پاسخ درست را برگرداند سرویس مجددا به مدار بازمیگردد در غیر این صورت زمان تمدید شده و مجدد درخواستی به سرور ارسال نمیشود.
  • Database per service
    • هر سرویس نیاز دارد بخشی از داده های مورد نیاز خود را از دیتابیس بخواند و بنویسد. از آنجایی که سرویس ها باید کاملا از هم مستقل باشند این الگو پیشنهاد میکند که هر سرویس دیتابیس خصوصی مخصوص خود را داشته و دسترسی به این دیتابیس ها تنها از طریق API هایی که سرویس فرآهم میکند باشد. در واقع دیتابیس نیز مانند پیاده سازی سرویس باید از بیرون از سرویس غیر قابل دسترسی باشد. این الگو مشابه اصل encapsolation در طراحی شی گرا است ولی در سطح سرویس ها.
  • Command Query Responsibility Segregation
    • در اصل قبلی بیان شد که دیتا های هر سرویس باید داخل سرویس به صورت خصوصی باشند و از خارج سرویس دسترسی به آنها ممکن نباشد. در این صورت امکان اجرای کوئری هایی که چند جدول از دیتابیس که جداول در سرویس های مختلف هستند وجود ندارد، این الگو مشکل فوق را حل میکند. برای حل این مشکل یک دیتابیس read only ایجاد شده و دیتاهای مورد نیاز درون آن قرار میگیرند. با هر تغییری که در دیتابیس سرویس ها انجام میشود این دیتابیس نیز تغییر میکند و برای اجرای کوئری های چند جدولی روی این دیتابیس کوئری اجرا میشود.


میکروسرویس یا monolithic ؟

یکی از مهم ترین تصمیماتی که یک معمار در ابتدا یا اواسط توسعه یک نرم افزار باید بگیرد انتخاب میان معماری بر پایه سرویس یا معماری monolithic است. رویه کلی این انتخاب به این شکل است که نرم افزار هایی که تیم توسعه کوچک، معماری ساده یا بودجه کمی برای توسعه دارند معماری monolithic را انتخاب کرده و نرم افزار های پیچیده تر معماری بر پایه سرویس را انتخاب میکنند. البته این موضوع مطلق نبوده و موضوعی نسبی است. در این فصل به برسی رویه کامل تری از این انتخاب و trade-off بین این دو معماری، همچنین روش های مهاجرت از معماری monolithic به معماری میکروسرویس پرداخته میشود.

در ابتدا یک تعریف از معماری monolithic ارائه میشود و انواع آن برسی میشود.

معماری monolithic

بهترین تعریف که برای معماری monolthic میتوان بیان کرد نرم افزاری است که تمام اجزای آن باید در کنار هم deploy شوند. البته این تعریف شامل طیف بزرگی از نرم افزار ها میشود اما به طور کلی نرم افزار های پیاده سازی شده با این معماری را میتوان به سه دسته کلی تقسیم کرد:

  1. The Single-Process Monolith :‌ در این نوع از معماری تمام پیاده سازی نرم افزار در یک مجموعه انجام میشود. البته دیتابیس از این مجموعه خارج است. بیشتر معماری های لایه ای مانند معماری MVC از این دست هستند.
  2. The Modular Monolith : در این نوع از معماری هر بخش از نرم افزار که اجزای آن عملکرد مشابه هم دارند در یک ماژول قرار گرفته و ماژول ها می توانند از هم مستقل باشند ولی باز هم تمام ماژول ها همزمان و در کنار هم deploy میشوند.
  3. The Distributed Monolith‌: این نوع از معماری مشابه معماری میکروسرویس است ولی تمام سرویس ها باید در کنار هم و روی یک سرویس دیپلوی شوند. به طور کلی استفاده از این معماری اکیدا توصیه نمیشود زیرا هم معایب معماری monolthic و هم معایب معماری میکروسرویس را در کنار هم دارد.


انتخاب بین این دو معماری

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

فارغ از بحث ساختار تیم ها تفاوت این دو معماری را میتوان از منظر قابلیت های هرکدام همچنین ویژگی های کیفی و موارد دیگر نیز برسی کرد.

در بحث performance هیچ یک از این دو معماری برتری نسبت به یکدیگر ندارند. البته پیاده سازی نرم افزار با معماری Monolith به دلیل این که ارتباط بین ماژول ها با سرعت بالا و زمان کم انجام میشود مزیت نسبی برای ویژگی پرفرمنس ایجاد میکند ولی این مزیت مطلق نیست. در معماری میکروسرویس میتوان با استفاده از تکنیک هایی مانند صف ها ، load balancer ها ، caching و … به پرفرمنس بالاتری دست پیدا کرد البته امکان استفاده از برخی از این ابزار ها در معماری Monolith نیز وجود دارد ولی معماری ماکروسرویس استفاده از این ابزار ها را راحت تر و کارامد تر میکند. همچنین در صورتی که کاربران نرم افزار به طور گسترده ای رشد کنند امکان توسعه مقیاس نرم افزار در معماری میکروسرویس بیشتر است پس scalability معماری میکروسرویس بالاتر میباشد.

موضوع بعدی بحث maintenance میباشد در این ویژگی کیفی معماری میکروسرویس مزیت مطلق نسبت به معماری Monolith دارد. زیرا هر سرویس به طور جداگانه توسعه داده شده و نگهداری و عیب یابی در یک سرویس کوچک بسیار ، بسیار راحت تر از یک نرم افزار Monolith نسبتا بزرگ میباشد.

معیار بعدی راحتی توسعه نرم افزار میباشد در این معیار چون معماری Monolith ساختار ساده تری دارد فرآیند توسعه آن راحت تر بوده پس در این معیار معماری Monolith مزیت دارد.

در موضوع Availability معماری میکروسرویس وضعیت بهتری دارد زیرا سرویس های آن به صورت مجزا deploy شده و این مزیت را ایجاد میکند که deploy های سبک تر با تغییرات کمتر انجام شود همچنین در صورت کار نکردن یک سرویس در محیط پروداکشن تمام نرم افزار از کار نیوفتاده و بقیه سرویس ها به فعالیت خود ادامه میدهند البته این موضوع باعث برتری ویژگی Reliability در معماری میکروسرویس نیز میشود.

میتوان نتیجه گرفت که در نرم افزار هایی که توسعه سریع و راحت مورد نظر است و ویژگی های Availability, Reliability ، scalability مورد نظر نمیباشد استفاده از معماری Monolith مزیت بیشتری دارد و در نرم افزار هایی که این موارد اهمیت دارند معماری میکروسرویس انتخاب بهتری میباشد.


مهاجرت از معماری Monolith به معماری میکروسرویس

ممکن است یک نرم افزار در مراحل ابتدایی توسعه خود به دلیل نیاز به توسعه سریع با معماری Monolith پیاده سازی شده باشد ولی در طول زمان با بزرگتر و پیچیده تر شدن نرم افزار نیاز باشد که هر ماژول آن توسط یک سرویس جدا پیاده سازی شده و توسط تیم مستقلی نگه داری شود پس نیاز است راهکار هایی معرفی شود که این فرآیند معاجرت را ساختارمند تر و ساده تر کند. به طور کلی برای مهاجرت از معماری monolith به ماکروسرویس نیاز نیست که تمام نرم افزار از اول تولید شود بلکه با روش هایی میتوان نرم افزار موجود را به سرویس های مختلف تقسیم کرد. عملیات این مهاجرت عملیاتی زمان بر میباشد که ممکن است ماه ها یا سال ها به طول انجامد. در طول این مهاجرت به احتمال زیاد نیاز است که قابلیت های جدیدی که از سمت کسب و کار یا تیم محصول یا کاربران تعیین میشوند به نرم افزار قبلی اضافه شود و فرآیند مهاجرت نیز به صورت موازی پیش رود. برای این منظور لازم است که در یک خط زمانی به صورت تدریجی سرویس ها از نرم افزار اصلی جدا شده و به صورت یک سرویس مستقل درآیند و نرم افزار monolith نیز در طول زمان کوچک تر و کوچک تر شده تا جایی که نرم افزار به مجموعه ای از سرویس ها تبدیل شود.

برای این پیاده سازی این استراتژی از سه راه حل میتوان استفاده کرد.

  • هر قابلیت جدید را به شکل یک سرویس جدید اضافه کرده یا به سرویس موجود اضافه میکنیم. این راه حل از این جهت دارای اهمیت است که جلوی بزرگتر شدن نرم افزار monolith را میگیرد و قسمت monolith این نرم افزار از وضعیت موجود بزرگتر نمیشود. یک روش خوب برای مدیریت درخواست ها به نرم افزار استفاده از API gateway میباشد به این شکل که درخواست هایی که مربوط به نرم افزار قدیمی میباشد به سمت آن نرم افزار مسیر یابی شود و درخواست هایی که مربوط به سرویس های جدید هستن به سمت سرویس های جدید.
  • جدا سازی ظاهر نرم افزار از کسب و کار. در این راه حل لایه کسب و کار به طور کلی از لایه ظاهری نرم افزار جدا شده و این دو از طریق API ها یا روش های مشابه با هم ارتباط برقرار میکنند. البته بیشتر نرم افزار های monolith امروزی به دو بخش front-end و back-end تقسیم میشوند که این دو معمولا دو نرم افزار مجزا میباشند. در این صورت نیازی به این راه حل برای مهاجرت از معماری monolith به ماکروسرویس نداریم.
  • یکی دیگر از راه حل ها جداسازی و تقسیم قسمت های مختلف معماری monolith موجود به سرویس های جدید میباشد. یک روش خوب برای این کار این است که domain های مختلف کسب و کار شناسایی شده و به ازای هر domain یک سرویس جدید ایجاد شود. با این کار به مرور قسمت monolith نرم افزار کوچک تر شده تا زمانی که تمام قسمت ها به سرویس تبدیل شوند.

با انجام این سه روش میتوان یک مهاجرت خوب و پایدار از معماری monolith به ماکروسرویس داشت.


نحوه کوچک تر شدن monolith و افزودن به سرویس ها در طول زمان
نحوه کوچک تر شدن monolith و افزودن به سرویس ها در طول زمان


برسی تکنیک های بهبود ویژگی های کیفی در معماری میکروسرویس

به طور کلی پیاده سازی نرم افزار با معماری ماکروسرویس باعث بهبود برخی از ویژگی های کیفی و افت عملکرد برخی دیگر از ویژگی های کیفی میشود. در این فصل تکنیک هایی معرفی میشود که تا جای ممکن از افت ویژگی های کیفی در معماری میکروسرویس جلوگیری شود یا حداقل وضعیت کمی بهتر شود همچنین برخی از این ویژگی ها که به شکل ذاتی توسط معماری میکروسرویس وضعیت آن بهتر میشود ، وضعیت بهتر آن حفظ شده یا بهبود های جزئی داشته باشند.

کارایی

در بحث کارایی همانطور که پیشتر اشاره شد معماری ماکروسرویس ضعیف تر از معماری های monolith عمل میکند. این به این دلیل است که اجزای این معماری از روش پیچیده تری برای ارتباط با هم استفاده میکنند. تکنیک بهبود پرفرمنس در این معماری حول محور روش هایی برای بهبود این ارتباط ها میباشد زیرا عدم کارایی در هر سرویس ارتباطی با معماری ماکروسرویس نداشته و باید تکنیک هایی برای بهبود آن سرویس محقق شود. به طور کلی دو دسته ارتباط در معماری ماکروسرویس وجود دارد، ارتباط همزمان و غیرهمزمان. در صورت استفاده از روش ارتباط هم زمان مشکل اصلی این است که در صورتی که یک سرویس به سرویس دیگر وابسته باشد سرویس وابسته بعد از درخواست باید منتظر جواب سرویس دیگر بماند و همین موضوع موجب کاهش پرفرمنس میشود. به عنوان مثال یک نرم افزار بانکی را در نظر بگیرید فرض کنید که در این نرم افزار دو سرویس وجود دارد که یک سرویس مربوط به انتقال وجه و سرویس دیگر لاگ های این انتقال را در یک دیتابیس سیو میکند. شیوه کار این سرویس ها به این شکل میباشد که ابتدا انتقال وجه انجام شده و سپس سرویس مربوط به ذخیره لاگ توسط سرویس انتقال وجه صدا زده میشود. در صورتی که این ارتباط از روش هم زمان استفاده کند سرویس انتقال وجه باید منتظر بازگشت درخواست سیو لاگ بماند و در صورتی که سرویس لاگ یا دیتابیسی که لاگ در آن ذخیره میشود زیر بار باشد و نتواند به سرعت نتیجه ذخیره لاگ را به سرویس انتقال بازگرداند، کارایی سرویس انتقال وجه نیز افت میکند. ولی با استفاده از روش غیر هم زمان پس از فراخوانی سرویس لاگ عملیات میتواند ادامه پیدا کند و نتیجه انتقال به کاربر نمایش داده شده و لاگ بعدا ذخیره شود.

روش های ارتباط سرویس ها در معماری ماکروسرویس به صورت مفصل در بخش آینده برسی میشود.

امنیت

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

از دیگر تکنیک های مهم استفاده از API gateway برای ارتباط با سرویس ها است به گونه ای که تمام ترافیک مربوط به فراخوانی API ها از این درگاه گذشته و با فرآهم کردن امنیت این درگاه میتوان تا حد زیادی ارتباط امن تری را تجربه کرد.

تست

در معماری ماکروسرویس هر سرویس میتواند به صورت جداگانه دارای unit test برای تست کلاس ها ، متد ها و غیره و integration test برای تست ارتباط میان ماژول های درون سرویس باشد. در این حالت دو مشکل اصلی وجود دارد مشکل اول این است که ممکن است یک ماژول از یک سرویس برای کار کردن نیاز به ماژولی از سرویس دیگر داشته باشد در این صورت لازم است که یک دیتای تستی برای نمونه ای از خروجی سرویس دوم برای تست سرویس اول فرآهم شود. مشکل بعدی این است که در این حالت covarage تست بالایی در هر سرویس وجود دارد ولی covarage تست برای ارتباط بین سرویس ها صفر میباشد. برای حل این مشکل میتوان سناریو های ارتباط سرویس ها با یکدیگر را استخراج کرد سپس برای تستی را توسعه داد که این سناریو را اجرا میکند. به عنوان مثال در یک تراکنش بانکی که چندین سرویس در ارتباط هستند میتوان با داده های تستی یک تراکنش تستی ایجاد کرد به طوری که تمام سرویس های مرتبط به طور کامل پوشش داده شوند.


برسی نحوه ارتباط سرویس ها با هم و ابزار های مرتبط

در معماری ماکروسرویس سرویس ها باید برای دریافت داده ها یا پیام ها با هم در ارتباط باشند. هرچند معماری بهتر به شکلی است که سرویس ها حداقل ارتباط را با هم داشته باشند ولی در برخی موارد این ارتباط اجتناب ناپذیر میباشد. به این ارتباط ، ارتباط سرویس با سرویس یا service-to-service communication یا S2S میگویند.

به طور کلی در نوع ارتباط در معماری ماکروسرویس وجود دارد. ارتباط همزمان و غیرهمزمان. ارتباط همزمان معمولا توسط پروتکل HTTP انجام شده و نتیجه مورد نظر در طول مدتی که ارتباط TCP برقرار است بازمیگردد. ولی در ارتباط غیر همزمان درخواست ها در یک صف قرار گرفته و به نوبت پردازش میشودند در این صورت هیچ درخواستی نادیده گرفته نشده و به همه درخواست ها پاسخ داده میشود.

به طور کلی در بیشتر کیس ها از ارتباط غیر همزمان استفاده میشود به جز موارد زیر.

  • از آنجا که در ارتباط همزمان امکان چک کردن موارد امنیتی و اعتبار سنجی در این پروتکل در لحظه انجام شده پس این روش برای شرایطی که به امنیت بالا احتیاج است مناسب تر است.
  • زمانی که به جواب یک درخواست در همان لحظه نیاز داریم.
  • به طور کلی کار با پروتکل HTTP ساده تر از ارتباط غیر همزمان میباشد پس این روش برای تیم هایی با تجربه کمتر مناسب است.

message queue

ابزار هایی هستند که یک محیط صف را برای ارتباط غیر همزمان سرویس ها فرآهم می کنند. به طور کلی به دو دسته تقسیم میشوند.

Point-to-point یا P2P

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

Publish-Subscribe یا Pub/Sub

این روش به ارسال کننده پیام اجازه میدهد پیام را هم زمان به چند سرویس متفاوت ارسال کند. به عنوان مثال هنگام ثبت نام کاربر در یک نرم افزار بر پایه ماکروسرویس ممکن است نیاز باشد که همزمان اطلاعات کاربر به یک سرویس مربوط به ذخیره اطلاعات کاربر در دیتابیس و یک سرویس مربوط به ذخیره لاگ ها ارسال شود. در این روش میتوان به صورت هم زمان این عملیات را انجام داد.

مقایسه دو ابزار message broker

در ابزار اصلی که به عنوان message broker استفاده میشوند kafka و rabbitmq میباشد. در جدول زیر این دو ابزار برسی شده اند.


رنگ قرمز به معنی عملکرد ضعیف و رنگ سبز به معنی عملکرد بهتر میباشد. این بنچمارد پس از کار با دو ابزار و همچنین برسی داکیومنت آنها تهییه شده است.
رنگ قرمز به معنی عملکرد ضعیف و رنگ سبز به معنی عملکرد بهتر میباشد. این بنچمارد پس از کار با دو ابزار و همچنین برسی داکیومنت آنها تهییه شده است.


برسی ابزار های مدیریت سرویس های معماری میکروسرویس

در معماری ماکروسرویس مدیریت سرویس ها از اهمیت بالایی برخوردار میباشد. به عنوان مثال در یک نرم افزار با ۲۰ سرویس متفاوت نیاز است که هر سرویس به صورت مستقل دیپلوی شود، لاگ های سیستم به ازای هر سرویس جمع آوری و تحلیل شود و همچنین منشا مشکلات سیستم مشخص شود. به این منظور از ابزار های متفاوتی میتوان استفاده کرد.

ابزار های ساخت کانتینر

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

Docker

یکی از مورد استفاده ترین ابزار ها برای ساخت کانتینر ابزار متن باز docker میباشد. شیوه کار این نرم افزار به این صورت است که داخل یک یا چند کانتینر فرآیند کامپایل شدن و اجرا شدن کد را به صورت خودکار انجام میدهد. خوبی استفاده از داکر در معماری ماکروسرویس این است که در صورتی که هر سرویس از تکلونوژی ها و زبان های برنامه نویسی متفاوتی استفاده کند داکر میتواند تمام این سرویس ها را بدون نیاز به پیاده سازی فرآیند نصب سرویس ها و به صورت خودکار انجام داده و در زمان و هزینه صرفه جویی کند.

فرآیند CI/CD

داکر میتواند فرآیند اجرای سرویس ها را برای توسعه دهندگان خودکار کند. ولی در روند deployment نیاز است که یک سری از عملیات های دیگر نیز خودکار شود این عملیات ها شامل استقرار سرویس روی سرور پرداکشن ، اجرای تست های اتوماتیک ، اجرای تغییرات روی دیتابیس ها و موارد دیگر میباشد. این کار توسط ابزار هایی با طراحی پایپ لاین انجام میشود. این پایپ لاین ها شامل چندین مرحله یا stage میباشند که هر stage وظیفه خواست خود را دارد. به عنوان مثال در یک پایپ لاین در مرحله اول کد با آخرین نسخه آپدیت شده ، در مرحله بعدی تست های اتماتیک اجرا شده و در مرحله آخر کانتینر آپدیت شده سرویس به جای کانتینر قبلی روی سرور قرار میگیرد و نسخه جدید آن سرویس را ارائه میکند.

ابزار های CI/CD

برای فرآیند ci/cd ابزار های متنوعی استفاده میشود در اینجا دو ابزار را برسی میکنیم

Gitlab-ci

این ابزار متن باز مربوط به شرکت gitlab میباشد و ارتباط خوبی با ریپازیتوری هایی که بر بستر gitlab میباشند برقرار میکند. برای اجرای این نرم افزار کافی است worker مربوط به آن را روی یک سرور اجرا کرده و ارتباط آن را با سروری که gitlab روی آن قرار دارد برقرار کنیم. سپس میتوانیم به کمک یک فایل تنظیمات مربوط به مراحل آن را پیاده سازی کرده و اجرا نماییم.

Jenkins

یک ابزار متن باز برای انجام فرآیند ci/cd مباشد که دارای پلاگین های زیادی است و ارتباط خوبی با تمام ابزار های کنترل ورژن دارد.

مقایسه این دو ابزار


مدیریت لاگ ها در معماری ماکروسرویس

مدیریت لاگ ها در معماری ماکروسرویس از اهمیت بالایی برخوردار میباشد. از این جهت که در صورت بروز مشکلی در سیستم باید به سرعت تشخیص داده شود که مشکل حاصل از کدام سرویس میباشد تا آن سرویس به سرعت دیباگ شده و مشکلاتش برسی شود به همین جهت نیاز به یک سرویس مجزا برای مدیریت لاگ میباشد. یکی از ابزار های کاربردی برای این کار نرم افزار elastic میباشد. این سرویس از سه نرم افزار مجزا تشکیل شده که هر سه نرم افزار کاملا با هم هماهنگ میباشند. این سه شامل elastic ، kibana و log stash میباشد که به طور مختصر به آن ELK میگویند.

Logstash:

این ابزار لاگ های ورودی را مرتب کرده و به یک فرمت استاندارد تبدیل میکند.

Elastic:

این ابزار لاگ ها را در یک دیتابیس ذخیره میکند.

Kibana:

این ابزار لاگ ها را نمایش داده و توسط نمودار هایی تحلیل آن را راحت تر میکند.



منابع

مقالات وب

  1. The History of Microservices: From Thought Experiment to Industry Standard, Muaath Bin Ali, 2023
  2. https://microservices.io
  3. The Basics of Service-to-Service Communication: A Beginner’s Guide
  4. Message Queues: A Key Concept in Microservices Architecture
  5. https://www.styra.com/blog/microservices-security-fundamentals-and-best-practices/
  6. https://martinfowler.com/articles/microservice-testing/#conclusion-test-pyramid
  7. https://kafka.apache.org/documentation/
  8. https://rabbitmq.com/
  9. https://www.docker.com/
  10. https://docs.gitlab.com/ee/ci/
  11. https://www.jenkins.io/
  12. https://www.elastic.co/elastic-stack

مقالات آکادمیک

  1. The Comparison of Microservice and Monolithic Architecture, Wojciech Zabierowski , 2022

کتاب ها

  1. Edition Building Microservices Designing Fine-Grained Systems second edition, o’reilly
  2. Microservices Patterns: With examples in Java First Edition, Chris Richardson

کنفرانس ها

  1. Microservices at Spotify Kevin Goldsmith GOTO


این مطلب، بخشی از تمرینهای درس معماری نرم‌افزار در دانشگاه شهیدبهشتی است.









نرم افزارمعماری میکروسرویسمعماری_نرم_افزار_بهشتی
شاید از این پست‌ها خوشتان بیاید