اگر از معماری Microservice استفاده می کنید و می خواهید در مورد الگوهای مختلف طراحی Microservice و اصول برای معماری بهتر برنامه خود بیاموزید، به جای درستی آمده اید. در این مقاله قصد دارم اصل و الگوهای ضروری طراحی میکروسرویس را به اشتراک بگذارم. ما الگوهایی مانند Event Sourcing، Circuit Breaker، SAGA، CQRS، Strangle و API Gateway و اصولی مانند Scailibity، Flexibility، Resiliency و غیره را پوشش خواهیم داد.
هنگام توسعه یک برنامه سازمانی، بهتر است به جای حرکت با یک معماری یکپارچه، با خدمات میکرو حرکت کنید.
در حالی که مواردی وجود دارد که می خواهید با معماری یکپارچه مانند برنامه های کاربردی با تاخیر کم پیش بروید، اما در بیشتر موارد که می خواهید برنامه جاوا خود را در فضای ابری اجرا کنید، معماری Microservice راه حل بهتری ارائه می دهد.
بنابراین بیایید نگاهی گذرا به میکروسرویس ها و موارد استفاده و الگوهای طراحی برای سرویس های میکرو داشته باشیم.
معماری میکروسرویس چیست؟
معماری میکروسرویس در حوزه کسب و کار ساختار یافته است و مجموعه ای از خدمات مستقل کوچک است. در معماری میکروسرویس، همه اجزاء مستقل هستند و حول یک قابلیت تجاری واحد میپیچند.
چرا باید به جای استفاده از معماری یکپارچه، معماری میکروسرویس را در نظر بگیریم؟ در زیر به چهار مفهوم اصلی اشاره شده است که اهمیت معماری میکروسرویس را نسبت به معماری یکپارچه توضیح می دهد.
1. دید بالا است - MSA دید بهتری را برای خدمات شما فراهم می کند.
2. انعطاف پذیری را بهبود می بخشد - انعطاف پذیری شبکه خدمات ما را بهبود می بخشد
3. کاهش زمان تولید - کاهش زمان تحویل از ایده تا محصول نهایی.
4. کاهش هزینه - هزینه کلی طراحی، پیاده سازی و نگهداری خدمات فناوری اطلاعات را کاهش دهید.
الگوها و اصول اساسی طراحی میکروسرویس
اکنون که میدانید معماری میکروسرویس چیست و چرا باید معماری میکروسرویس را برای ساخت برنامههایی در نظر بگیرید که میتوانند آزمایش زمان را تحمل کنند و به اندازه کافی مقیاسپذیر باشند تا بتوانند ترافیک دنیای واقعی را مدیریت کنند، بیایید اکنون به اصل اساسی Microservices و الگوی طراحی بپردازیم. شما می توانید برای حل مشکلات رایج مرتبط با معماری میکروسرویس استفاده کنید.
بیایید به اصولی نگاه کنیم که در آن معماری میکروسرویس ساخته شده است.
1. مقیاس پذیری
2. انعطاف پذیری
3. مستقل و خودمختار
4. حکمرانی غیر متمرکز
5. انعطاف پذیری
6. جداسازی شکست.
7. تحویل مداوم از طریق DevOps
در عین رعایت اصول فوق، ممکن است مشکلات دیگری نیز وجود داشته باشد که توسعه دهندگان ممکن است به آن دچار شوند و برای جلوگیری از این امر، می توانیم از الگوهای طراحی در معماری میکروسرویس استفاده کنیم.
در این مقاله قصد داریم به 10 الگوی اصلی طراحی بپردازیم که در زیر به آنها اشاره شده است.
1. پایگاه داده در هر میکروسرویس
2. رویداد منبع یابی
3. CQRS
4. حماسه
5. BFF
6. API Gateway
7. خفه کننده
8. مدار شکن
9. پیکربندی خارجی
10. ردیابی قرارداد مبتنی بر مصرف کننده
بنابراین ابتدا با الگوی طراحی Database per Microservice شروع کنید.
1. پایگاه داده در الگوی میکروسرویس
طراحی پایگاه داده به سرعت در حال پیشرفت است و در هنگام توسعه راه حل مبتنی بر میکروسرویس، موانع متعددی وجود دارد که باید بر آنها غلبه کرد. معماری پایگاه داده یکی از مهمترین جنبه های میکروسرویس ها است.
بهترین راه برای ذخیره سازی داده ها چیست و در کجا باید ذخیره شود؟
هنگام استفاده از معماری میکروسرویس باید دو گزینه اصلی برای سازماندهی پایگاه های داده وجود داشته باشد.
پایگاه داده در هر سرویس
پایگاه داده مشترک
1.1 پایگاه داده در هر سرویس.
مفهوم سرراست است. برای هر میکروسرویس (کل طرح یا جدول) یک ذخیره داده وجود دارد. سایر سرویسها نمیتوانند به مخازن دادهای که کنترل نمیکنند دسترسی پیدا کنند. چنین راه حلی مزایای زیادی دارد.
از طرف دیگر، ذخیره سازی داده های فردی به راحتی قابل مقیاس است. علاوه بر این، میکروسرویس دادههای دامنه را کپسوله میکند. در نتیجه، درک سرویس و داده های آن به عنوان یک کل بسیار آسان تر است. به ویژه برای اعضای تیم توسعه جدید بسیار مهم است.
زمان و تلاش کمتری از آنها برای درک درست منطقه ای که مسئولیت آن را بر عهده دارند، خواهد گرفت. اشکال اصلی این سرویس پایگاه داده این است که در صورت از کار افتادن ارتباط، نیاز به مکانیزم حفاظت از خرابی وجود دارد.
پایگاه داده در هر نمونه الگوی میکروسرویس
1.2 پایگاه داده مشترک
استفاده از پایگاه داده مشترک یک ضد الگو است. با این حال جای سوال دارد. مسئله این است که وقتی میکروسرویس ها از یک پایگاه داده مشترک استفاده می کنند، ویژگی های کلیدی خود یعنی مقیاس پذیری، استحکام و استقلال را از دست می دهند. در نتیجه، Microservices به ندرت از یک پایگاه داده مشترک استفاده می کنند.
هنگامی که به نظر می رسد یک پایگاه داده مشترک بهترین راه حل برای یک پروژه میکروسرویس است، ما باید در مورد اینکه آیا میکروسرویس واقعاً ضروری است، تجدید نظر کنیم. شاید یکپارچه گزینه بهتری باشد. بیایید نگاهی به نحوه عملکرد یک پایگاه داده مشترک بیندازیم.
استفاده از یک پایگاه داده مشترک با میکروسرویس ها یک سناریوی متداول نیست. در حین انتقال یک مونولیت به میکروسرویس ها می توان یک حالت موقت ایجاد کرد. مدیریت تراکنش مزیت اساسی یک پایگاه داده مشترک در مقابل پایگاه داده هر سرویس است. نیازی به پخش تراکنش ها در بین سرویس ها نیست.
2. الگوی منبع یابی رویداد
منبع رویداد مسئول ارائه یک ترتیب جدید از رویدادها است. حالت برنامه را می توان با استفاده از کوئری داده ها بازسازی کرد و برای انجام این کار، باید هر تغییری را در وضعیت برنامه دوباره تصویر کنیم. منبع رویداد بر این ایده استوار است که هر تغییری در وضعیت موجودیت باید توسط سیستم ثبت شود.
تداوم یک کالای تجاری با ذخیره یک سری رویدادهای تغییر وضعیت انجام می شود. هر بار که وضعیت یک شیء تغییر می کند، یک رویداد جدید به دنباله رویدادها اضافه می شود. اساساً اتمی است زیرا یک عمل است. با پخش مجدد اتفاقات یک موجودیت، می توان وضعیت فعلی آن را بازسازی کرد.
فروشگاه رویداد برای پیگیری همه رویدادهای شما استفاده می شود. فروشگاه رویداد به عنوان یک کارگزار پیام و همچنین پایگاه داده رویدادها عمل می کند. این امکان را به سرویس ها می دهد که از طریق یک API در رویدادها مشترک شوند. فروشگاه رویداد اطلاعات مربوط به هر رویدادی را که در پایگاه داده ذخیره می شود به همه مشترکین علاقه مند ارسال می کند. در معماری میکروسرویس های رویداد محور، فروشگاه رویداد پایه و اساس است.
این الگو را می توان در سناریوهای زیر استفاده کرد:
حفظ ذخیره سازی داده های موجود بسیار مهم است.
نباید هیچ تغییری در پایگاه کد لایه داده موجود ایجاد شود.
تراکنش ها برای موفقیت برنامه بسیار مهم هستند.
بنابراین از بحث بالا، به وضوح نشان داده می شود که منبع رویداد به چالش اجرای یک معماری رویداد محور می پردازد. میکروسرویس ها با پایگاه های داده مشترک نمی توانند به راحتی مقیاس شوند. پایگاه داده نیز یک نقطه شکست واحد خواهد بود. تغییرات در پایگاه داده می تواند بر تعدادی از خدمات تأثیر بگذارد.
3. الگوی بخش بندی پرس و جوی فرمان (CQRS).
در بالا، ما در مورد منبع رویداد بحث کرده ایم. در این تاپیک قصد داریم به بحث CQRS بپردازیم؟ می توانیم با دستورات و پرس و جو موضوع را به دو قسمت تقسیم کنیم.
دستورات - وضعیت شی یا موجودیت را تغییر دهید.
کوئری ها - وضعیت موجودیت را برمی گرداند و چیزی را تغییر نمی دهد.
در سیستم های مدیریت داده های سنتی، مسائلی وجود دارد،
1. خطر جدال داده ها
2. مدیریت عملکرد و امنیت پیچیده است زیرا اشیا در معرض هر دو برنامه خواندن و نوشتن قرار دارند.
بنابراین برای حل این مشکلات، CQRS به تصویر بزرگ می آید. CQRS مسئول تغییر وضعیت موجودیت یا برگرداندن نتیجه است.
مزایای استفاده از CQRS در زیر مورد بحث قرار گرفته است.
1. پیچیدگی سیستم با جداسازی مدلهای پرس و جو و دستورات کاهش مییابد.
2. می تواند چندین نما برای اهداف پرس و جو ارائه کند.
3. می تواند سمت خواندن سیستم را جدا از سمت نوشتن بهینه کند.
سمت نوشتن مدل، تداوم رویداد را کنترل می کند و به عنوان منبع اطلاعات برای طرف خوانده شده عمل می کند. مدل خواندن سیستم، نماهای مادی شده از داده ها را تولید می کند که اغلب نماهایی به شدت غیرعادی شده هستند.
4. SAGA
SAGA یکی از بهترین راه حل ها برای حفظ سازگاری با داده ها در معماری توزیع شده بدون داشتن اصول ACID است. SAGA مسئول انجام تراکنش های تفسیری متعدد با دادن فرصت های برگشتی است.
دو راه برای رسیدن به حماسه وجود دارد
1. رقص
2. ارکستراسیون.
در این حماسه رقص، ارکستراسیون مرکزی وجود ندارد. هر سرویس در Saga تراکنش خود را انجام می دهد و رویدادها را منتشر می کند. سایر سرویس ها به این اتفاقات پاسخ می دهند و وظایف خود را انجام می دهند. علاوه بر این، بسته به سناریو، ممکن است رویدادهای اضافی را منتشر کنند یا نکنند.
در حماسه Orchestration، هر سرویسی که در حماسه شرکت می کند، تراکنش های خود را انجام می دهد و رویدادها را منتشر می کند. سایر سرویس ها به آن رویدادها پاسخ می دهند و وظایف خود را تکمیل می کنند.
مزیت استفاده از SAGA
1. می تواند برای حفظ ثبات داده ها در چندین سرویس بدون اتصال محکم استفاده شود.
مضرات استفاده از SAGA
1. پیچیدگی الگوی طراحی SAGA از دیدگاه برنامه نویس زیاد است و توسعه دهندگان به نوشتن حماسه ها به عنوان تراکنش های سنتی عادت ندارند.
5. Backend For Frontend (BFF)
این الگو برای شناسایی نحوه واکشی داده ها بین سرور و کلاینت ها استفاده می شود. در حالت ایده آل، تیم فرانت اند مسئول مدیریت BFF خواهد بود.
یک BFF منفرد وظیفه مدیریت رابط کاربری واحد را بر عهده دارد و به ما کمک میکند تا جلوی صفحه را ساده نگه داریم و دادههای نمای یکپارچه را از طریق باطن ببینیم.
چرا BFF به برنامه میکروسرویس ما نیاز دارد؟
هدف این معماری جدا کردن برنامه های جلویی از معماری باطن است.
به عنوان یک سناریو، به این فکر کنید که برنامهای دارید که از برنامه تلفن همراه، برنامه وب تشکیل شده و نیاز به ارتباط با خدمات پشتیبان در معماری میکروسرویس دارد.
این را می توان با موفقیت انجام داد، اما اگر می خواهید تغییری در یکی از سرویس های frontend ایجاد کنید، باید به جای به روز رسانی یک سرویس، یک نسخه جدید را مستقر کنید.
بنابراین در اینجا معماری میکروسرویس می آید و این می تواند درک کند که برنامه های ما به چه چیزی نیاز دارند و چگونه خدمات را مدیریت کنند.
این یک پیشرفت بزرگ در معماری میکروسرویس است، زیرا این امکان را میدهد تا باطن برنامه را از قسمت جلویی جدا کنید. یکی دیگر از مزیتهایی که میتوانیم از این BFF دریافت کنیم این است که میتوانیم دوباره از کد استفاده کنیم، زیرا این امکان را به همه مشتریان میدهد تا از کدهای backend استفاده کنند.
بین سرویس گیرنده و سایر APIهای خارجی، خدمات و غیره، BFF مشابه یک سرور پروکسی عمل می کند. اگر درخواست باید از مؤلفه دیگری عبور کند، بدون شک تأخیر افزایش می یابد.
6. API Gateway
این الگوی معماری میکروسرویس واقعاً برای برنامه های بزرگ با برنامه های مشتری متعدد خوب است و وظیفه ارائه یک نقطه ورودی واحد برای گروه خاصی از میکروسرویس ها را بر عهده دارد.
دروازه API بین برنامه های مشتری و میکروسرویس ها قرار می گیرد و به عنوان یک پروکسی معکوس عمل می کند و درخواست های مشتری را به خدمات ارسال می کند. احراز هویت، خاتمه SSL، و کش کردن برخی از دیگر خدمات مقطعی است که می تواند ارائه دهد.
چرا به جای استفاده از ارتباط مستقیم مشتری به میکروسرویس، معماری دروازه API را در نظر می گیریم؟ در این مورد با مثال های زیر بحث خواهیم کرد
1. مسائل امنیتی - همه میکروسرویسها باید بدون دروازه در معرض «جهان خارجی» قرار گیرند و سطح حمله را در مقایسه با پنهان کردن میکروسرویسهای داخلی که برنامههای مشتری مستقیماً به آنها دسترسی ندارند، افزایش میدهد.
2. نگرانی های متقابل - مجوز و SSL باید توسط هر میکروسرویس منتشر شده عمومی انجام شود. این مشکلات ممکن است در بسیاری از موارد در یک سطح حل شوند و تعداد ریزسرویس های داخلی کاهش یابد.
3. جفت - برنامه های مشتری بدون الگوی API Gateway به میکروسرویس های داخلی گره خورده اند. برنامه های مشتری باید بدانند که چگونه میکروسرویس ها بخش های مختلف برنامه را تجزیه می کنند.
آخرین اما نه کماهمیت، دروازه API میکروسرویس باید قادر به مدیریت خرابیهای جزئی باشد. شکست یک میکروسرویس پاسخگو نباید منجر به شکست کل درخواست شود.
یک دروازه API میکروسرویس می تواند با خرابی های جزئی به روش های مختلفی مقابله کند، از جمله:
از داده های درخواست قبلی که کش شده است استفاده کنید.
برای داده های حساس به زمان که تمرکز اصلی درخواست است، یک کد خطا را برگردانید.
یک مقدار خالی ارائه کنید
به ارزش ۱۰ سخت افزاری تکیه کنید.
7. خفه کننده
الگوی طراحی Strangler یک الگوی طراحی محبوب برای تبدیل تدریجی برنامه یکپارچه شما به میکروسرویس ها با جایگزینی عملکرد قدیمی با یک سرویس جدید است. پس از آماده شدن قطعه جدید، قطعه قدیمی خفه می شود و قطعه جدید مورد استفاده قرار می گیرد.
رابط نما، که به عنوان رابط اصلی بین سیستم قدیمی و سایر برنامهها و سیستمهایی که آن را نامیدهاند، عمل میکند، یکی از مهمترین اجزای الگوی خفهکننده است.
برنامهها و سیستمهای خارجی میتوانند کد مرتبط با یک عملکرد خاص را شناسایی کنند، در حالی که کد سیستم تاریخی زیربنایی توسط رابط نما پنهان میشود. طراحی Strangler با الزام توسعهدهندگان به ارائه یک رابط نمای ظاهری که به آنها اجازه میدهد تا خدمات و عملکردهای فردی را هنگامی که آنها را از یکپارچه رها میکنند، در معرض دید قرار دهند.
شما باید کیفیت و قابلیت اطمینان سیستم خود را درک کنید، چه با کدهای قدیمی کار می کنید، چه فرآیند خفه کردن سیستم قدیمی خود را شروع کرده اید یا یک برنامه جدید کانتینری را اجرا کنید. وقتی مشکلی پیش میآید، باید بدانید که سیستم چگونه به آنجا رسیده است و چرا آن مسیر را طی کرده است.
8. الگوی مدار شکن
قطع کننده مدار راه حلی برای شکست تماس های راه دور یا قطع بدون پاسخ تا رسیدن به محدودیت زمانی است. اگر تماسگیرندگان زیادی با تامینکنندهای پاسخگو نداشته باشید، میتوانید منابع حیاتی خود را تمام کنید و این منجر به خرابی چندین سیستم در برنامهها میشود.
بنابراین در اینجا الگوی قطع کننده مدار می آید که یک فراخوانی تابع محافظت شده را در یک شیء قطع کننده مدار جمع می کند که خرابی را نظارت می کند. هنگامی که تعداد خرابی ها به یک سطح خاص می رسد، قطع کننده مدار قطع می شود و تمام تماس های بعدی با کلید مدار منجر به خطا یا یک سرویس یا پیام پیش فرض متفاوت می شود، نه اینکه تماس محافظت شده اصلا برقرار شود.
حالت های مختلف در الگوی قطع مدار
بسته - وقتی همه چیز طبق روال عادی به خوبی کار می کند، کلید مدار در این حالت بسته باقی می ماند.
باز - هنگامی که تعداد خرابی های سیستم از حداکثر آستانه فراتر رود، این منجر به باز شدن حالت باز می شود. این خطا برای تماس های بدون اجرای تابع را نشان می دهد.
باز - نیمه - پس از چندین بار اجرای سیستم، کلید مدار به حالت نیمه باز می رود تا بررسی شود که مشکلات اساسی هنوز وجود دارد.
9. پیکربندی خارجی
اغلب سرویس ها باید در محیط های مختلف اجرا شوند. به پیکربندی محیطی خاص مانند کلیدهای مخفی، اعتبار پایگاه داده و غیره نیاز است. تغییر سرویس برای هر محیط دارای تعدادی اشکال است. بنابراین چگونه میتوانیم یک سرویس را فعال کنیم تا در چندین محیط بدون تغییر اجرا شود؟
در اینجا الگوی پیکربندی Externalized آمده است زیرا این امکان خارجی سازی تمام تنظیمات برنامه از جمله اعتبار پایگاه داده و مکان شبکه را فراهم می کند.
به عنوان مثال، چارچوب Spring Boot پیکربندی خارجی را فعال می کند، که به شما امکان می دهد پیکربندی را از منابع زیادی بخوانید و به طور بالقوه تنظیمات پیکربندی مشخص شده قبلی را بر اساس ترتیب خواندن تغییر دهید. خوشبختانه FastAPI دارای پشتیبانی داخلی برای پیکربندی خارجی است.
10. ردیابی قرارداد مبتنی بر مصرف کننده
هنگامی که یک تیم در حال ساخت چندین سرویس مرتبط به طور همزمان به عنوان بخشی از یک تلاش نوسازی است، و تیم شما «زبان دامنه» بافت محدود را میداند اما ویژگیهای مجزای هر مجموعه و بار رویداد را نمیداند، رویکرد قراردادهای مبتنی بر مصرفکننده ممکن است موثر باشد
الگوی ردیابی قرارداد مبتنی بر مصرف کننده در میکروسرویس
این الگوی میکروسرویس در کاربردهای قدیمی که شامل یک مدل داده بزرگ و سطح سرویس موجود است مفید است. این الگوهای طراحی مسائل زیر را برطرف می کند:
1. چگونه می توانید بدون شکستن کلاینت های پایین دستی به یک API اضافه کنید.
2. چگونه بفهمیم چه کسی از سرویس آنها استفاده می کند.
3. نحوه ایجاد چرخه های کوتاه مدت با تحویل مداوم.
در معماری رویداد محور، بسیاری از میکروسرویس ها دو نوع API را در معرض دید قرار می دهند:
1. RESTful API از طریق HTTP
2. HTTP و API مبتنی بر پیام RESTful API امکان یکپارچه سازی همزمان با این سرویس ها و همچنین قابلیت های جستجوی گسترده را برای سرویس هایی که رویدادها را از یک سرویس دریافت کرده اند را فراهم می کند.
به طور خلاصه، یک رویکرد مبتنی بر مصرفکننده گاهی اوقات هنگام شکستن یک میراث یکپارچه استفاده میشود
همه این موارد در الگوی و اصول طراحی میکروسرویس است. در این آموزش همچنین در مورد معماری میکروسرویس و مهمترین الگوهای طراحی آن صحبت کرده ایم. معماری میکروسرویس و محاسبات ابری دست به دست هم می دهند زیرا معماری میکروسرویس توسعه و استقرار در فضای ابری را آسان تر می کند.
همچنین مقیاس پذیری Microservice با استفاده از Docker و Kubernetes آسان تر است و به همین دلیل است که شرکت های بیشتری به معماری Microservice روی می آورند. در عین حال، ایجاد یک راه حل Microservice که بتواند آزمایش زمان را در تولید تاب بیاورد، آسان نیست و اینجاست که دانش این الگوها و اصول محبوب Microservice کمک می کند.