مرتضی دلیل
مرتضی دلیل
خواندن ۷ دقیقه·۳ سال پیش

آموزش میکروسرویس Microservice - تحلیل یک پروژه کوچک بر اساس میکروسرویس ها (بخش سوم)

بخش اول : آشنایی با مفهوم میکروسرویس
بخش دوم : ویژگی های اصلی یک میکروسرویس
بخش سوم : تحلیل یک پروژه کوچک بر اساس میکروسرویس ها (همین مقاله)
بخش چهارم : شروع پیاده سازی یک پروژه فروشگاهی
پیشنیاز 1 بخش پنجم : آموزش Node و Typescript برای تولید api
پیشنیاز 2 بخش پنجم : آموزش داکر و مفاهیم اولیه
بخش پنجم : پیاده سازی یک میکروسرویس برای نمایش کالاها
پیشنیاز 1 بخش ششم : آشنایی با Asp.net core 6
بخش ششم : پیاده سازی یک میکروسرویس برای کار با سبد خرید
بخش هفتم : پیاده سازی یک میکروسرویس برای محاسبه قیمت و تخفیفات
بخش هشتم: پیاده سازی یک میکروسرویس برای ثبت سفارش


برای دیدن ویدیوهای من در مورد برنامه نویسی عضو این کانال شوید :
https://t.me/mediapub_channel

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

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

قبل از شروع تحلیل، اگر چنین پروژه ای به شما واگذار شود قبل از هر چیز به چه موضوعی فکر میکنید؟
من به موضوع کمیت تیم برنامه نویسی فکر میکنم.

تیم برنامه نویسی من چند نفره است؟

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

دقیقا مشابه این موارد را میتوان برای پیاده سازی Clean Architecture در یک پروژه کوچک تعمیم داد. چرا باید یک پروژه که از تعدادی api محدود تشکیل شده، بیزنس ساده ای دارد و توسط یک نفر توسعه می یابد و قرار نیست ماه ها و سال ها تغییر کند با معماری Clean و با دقت در تفکیک لایه ها انجام شود؟

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

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

  1. از یک فریم ورک یا لایبرری جدا مثل ری اکت یا انگولار برای UI استفاده نکنم و با Asp Core MVC پروژه را انجام دهم. که پابلیش یکپارچه داشته باشم و هر بار برای توسعه و تست مجبور به کار کردن با دو پروژه جدا و نگهداری و تست دو پروژه نباشم.
  2. معماری Clean Architecture و CQRS را پیاده سازی کنم چون سایت نیاز به توسعه دارد و امکان تغییر لایه ها و حتا دیتابیس در آینده وجود دارد. برای CQRS شک دارم، چون بعید است بخواهم Command ها و Query ها را در دو دیتابیس(یا روش) جدا و با ریپازیتوری جدا پیاده سازی کنم اما لحاظ کردن قواعد اولیه CQRS چندان زحمتی به من نمیدهد. (فوقش دو تا ریپازیتوری برای هر Entity میسازم)
  3. میکروسرویس به درد من نمیخورد چون با توجه به مورد 1 و اینکه خودم به تنهایی توسعه سایت را بر عهده دارم مزیتی برای شکستن پروژه به سرویس های کوچک نمیبینم.

با توجه به تمامی موارد گفته شده و فرض اینکه میکروسرویس برای این سیستم بهترین روش است، تحلیل این مثال را شروع میکنم.

نگاه از بالا به پروژه
نگاه از بالا به پروژه

از ساده ترین زاویه به پروژه نگاه میکنیم. تصویر فوق نشان میدهد که کاربر قرار است یک ریکوئست برای اضافه کردن آیتم به سبد خرید به سمت سرور ارسال کند. Gateway این ریکوئست را دریافت میکند و به سرویس(یا سرویس ها) میفرستد و نتیجه تولید شده از طریق همین Gateway به کاربر نمایش داده میشود.

اتفاق های جالب در پشت API Gateway افتاده که توانسته است ریسپانس مناسب را تولید کند. برای به روزرسانی سبد و اضافه شدن کالای جدید به سبد، API Gateway از چند میکروسرویس استفاده میکند. هر میکروسرویس پروسه جدا دارد و ارتباطات در این مثال در بستر HTTP صورت میگیرد.

جزئیات اتفاقات در تصویر زیر مشخص است :

  • بخش API Gateway مسئول یک اعتبارسنجی اولیه از درخواست دریافتی است. به محض ولید شدن، کار ابتدا به میکروسرویس Shopping Cart و سپس به میکروسرویس Price Calculation سپرده میشود.
  • میکروسرویس Shopping Cart از میکروسرویس دیگری به نام Product Catalog استفاده میکند تا اطلاعات لازم در مورد کالا را دریافت کند. سپس این میکروسرویس اطلاعات سبد کالای کاربر را در دیتابیس خود ذخیره میکند،و این اطلاعات را به API Gateway هم ارسال میکند. به منظور پرفورمنس این میکروسرویس اطلاعات سبد کالای مشتری را (که از میکروسرویس Product Catalog دریافت کرده) Cache میکند. تا برای دفعات بعد از ارتباط بینِ میکروسرویسی بینیاز باشد.
  • میکروسرویس Price Calculation وظیفه محاسبه قیمت و تخفیفات را برای تکمیل سبد کالای مشتری به عهده دارد.

همانطور که میبینید هر میکروسرویس وظیفه منحصر بفرد و تخصصی خودش را در این روند ایفا میکند و از میکروسرویس های دیگر در حدی که نیاز دارد خبر دارد. به عنوان مثال میکروسرویس price calculation هیچ اطلاعاتی در مورد کالاهایی که در میکروسرویس product catalog ذخیره شده ندارد. این موضوع مفهوم اصلی میکروسرویس است که هر جزء مسئولیت منحصر به فرد خودش را دارد.

تا اینجای کار سبد کالای کاربر تشکیل شده است. اما بررسی دو موضوع دیگر در صورت مساله خواسته شده است:

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

این اتفاقات نیازی به بازگرداندن فیدبک به کاربر ندارند. یعنی میتوانند به طور موازی حین پاسخگویی به request انجام شوند. این نوع عملیات یا اکشن ها را میتوانیم به عنوان سایدافکت های یک درخواست در نظر بگیریم. سایدافکت ها تاثیر مستقیم روی ریکوئست کاربر ندارند. (ارسال ایمیل یا اس ام اس در صورتی که محتوای اطلاع رسانی[و نه اعتبارسنجی] داشته باشند میتوانند ساید افکت یک فرایند باشند)

این اضافات را به Shopping cart microservice اضافه کنید.

در تصویر فوق دیده میشود که یک رویداد (event) به موازات درخواست کاربر برای به روزرسانی سبد اتفاق خواهد افتاد. این رویداد به نام ItemAddedToCart است و توسط میکروسرویس Shopping cart اتفاق می افتد. دیگر میکروسرویس هایی که مسئولیت کارهای موازی را دارند یعنی Recommendations و Shopping Tracking باید عضو(Subscribe) این رویداد(event) شوند. در حقیقت این میکروسرویس ها شنونده هستند و هر موقع رویداد اتفاق بیفتد این دو سرویس شنونده خواهند بود و اطلاعات را دریافت کرده و وظایف خود را انجام خواهند داد.

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


تصویر کامل

در مجموع شش میکروسرویس در تصویر وجود دارند که یک ریکوئست را به ریسپانس تبدیل میکنند و یک کالا را به سبد کاربر اضافه میکنند. هیچ کدام از این میکروسرویس ها از فرایند داخلی دیگر سرویس ها خبر ندارند. پنج تا از این ها data store خودشان را دارند که تنها موظف به کاریست که در حوزه فعالیت میکروسرویس خودش تعریف شده است. اکثر این میکروسرویس ها به شکل synchronously در بستر ریکوئست کاربر عمل میکنند و بعضی هم به شکل asynchronously اتفاق می افتند(event ها).

نمای کامل از فرایند ثبت کالا در سبد کاربر
نمای کامل از فرایند ثبت کالا در سبد کاربر


در بخش بعدی شروع به پیاده سازی مثال دیگری مشابه همین مثال خواهیم کرد.

برنامه نویسیمیکروسرویسآموزش میکروسرویسmicroserviceapi gateway
برنامه نویس و علاقمند به برنامه نویسی، سینما، فلسفه و هر چیزی که هیجان انگیز باشد. در ویرگول از روزمرگیهای مرتبط با علاقمندیهام خواهم نوشت. در توئیتر و جاهای دیگر @mortezadalil هستم.
شاید از این پست‌ها خوشتان بیاید