یک معماری میکروسرویس اصولی باید در ابتدا از دو اصل مهم پیروی کنه.
۱) loosely coupling
۲) high cohesion
اولی میگه که سرویس ها به هیچ عنوان نباید به هم وابستگی شدید یا (tight coupling) داشته باشند. سرویس ها نباید جزئیاتشون برای مصرف کننده هاشون (consumers) شفاف باشه. در این صورت تغییر در یک سرویس مصرف کننده هاشو از کار نمیندازه.
پس در همون مرحله اول ایجاد معماری میکروسرویس که میتونه تعیین مرز های سرویس ها باشه (service boundary) باید این موضوع در نظر گرفته بشه که سرویس ها نباید از جزئیات همدیگه اطلاع داشته باشن.
به نظرم تا وارد این مسئله تعیین مرز های سرویس ها شدیم خوبه به یادآوری بشه که تعیین مرز های سرویس ها یکی از مهم ترین مراحل چیدن معماری میکروسرویس برای یک پروژه است. غالبا شما وقتی میخاین یه معماری رو از صفر بچینید و یا حتی یه معماری monolithic رو بشکونید و تبدیل به میکروسرویس ها کنید (که به این کار decomposition میگن) در ابتدای امر احساس نیاز شدیدی خواهید کرد در مورد اینکه خب کدوم فیچر ها و کدوم بخش ها باید به عنوان یه سرویس جدا کار کنند .
کدوم فیچر ها باید باهم باشن و کدوم یکی ها باید جدا بشن. این کار به دو روش میتونه صورت بگیره.آقای کریس ریچاردسون ( chris richardson ) در کتاب microservice patterns میفرماید که میکروسرویس هاتونو یا بر اساس بیزنس لاجیک و قابلیت کسب و کار تجزیه کنید یا بر اساس ساب دامنه ها
اگر یکم متمرکز بخایم به معماری میکروسرویس نگاه کنیم میبینم که خیلی روی اصل مستقل بودن و انجام یک کار به خصوص به نحو احسن همانطور که جناب سم نیومن میفرماید (Small, and Focused on Doing One Thing Well) تاکید داره.
از طرف دیگه هم عمو باب (robert c. martin) میگه که همه چیزایی که به یک دلیل تغییر میکنن رو یه جا نگه دار و همه چیزایی که به دلایل متفاوت تغییر میکنن رو جدا کن از هم. اگر این صحبت و اون دید آقای سم نیومن رو بزاریم کنار هم میبینم که درواقع سرویس ها خیلی راحت بر اساس بیزنس لاجیک تقسیم میشن.
اما در تعیین مرز میکروسرویس ها باید به چنتا نکته مهم توجه بشه.
میکروسرویس ها باید کوچک باشند. فلسفه میکروسرویس به ما اجازه این رو نمیده که سرویس هامون خیلی بزرگ بشن و توصیه میکنه که تا حد ممکن سرویس هارو کوچک کنیم.
آنقدر کوچک که فقط یه کار انجام بدن.(یک کار منظور یه بخش از بیزنس لاجیک)
آنقدر کوچک که در صورت به مشکل خوردن فقط یه بخش کوچک از پروژه از کار بیوفتد.
آنقدر کوچک که در دو هفته قابل بازنویسی باشد (jon evas)
آنقدر کوچک که تیمی که روش کار میکنه با یه پیتزا سیر بشه(Amazon)
انقدر کوچک که دیگه حس بزرگی نداشته باشیم بهش.
ولی از نظر منطقی و به نظر من یه میکروسرویس وقتی به اندازه کافی کوچک شده که نیاز به یه تیم بزرگ برای توسعه و مدیریتش نداشته باشیم.
اگر یه میکروسرویس با ی تیم کوچک مدیریت نشه باید اونه تکه تکه کرد.
درواقع هرچی سرویس کوچکتر باشد معایب میکروسرویس ها کمتر / بهره وری بیشتر میشه و مزایای وابستگی متقابل (interdependency) افزایش می یابد ولی خب ازین مسئله قافل نشیم که تعداد سرویس ها با کوچکتر شدنشون بیشتر میشه و نگهداری (maintenance) سخت تر میشه.
سرویس ها باید ایزوله باشن.
تمامی ارتباطات سرویس ها باید از طریق شبکه باشه تا از (tight coupling) جلوگیری شود.
سرویس ها باید به صورت جدا از هم تغییر کنند و مستقر شوند.
باید به صورت روشن و شفاف بدانیم که هر سرویس چه چیزهایی را باید expose کند برای مصرف کننده هاش و چه چیزهایی رو باید مخفی کند. اگر اشتراک گذاری با سرویس مصرف کننده زیاد باشد . سرویس مصرف کننده به نمایش داخلی سرویس خیلی وابسته میشه و اصل loosely coupling نقض میشه.
وقتی سرویس ها tight coupled باشند باعث کاهش خودمختاری سرویس ها میشه زیرا در هنگام تغییر نیاز به هماهنگی اضافی با مصرف کننده های اون سرویس به شدت حس میشه.
در واقع باید به decoupling زیاد فکر کنیم در تعیین مرز های سرویس هامون.
قاعده طلایی ::: آیا میتوانید تغییر در یک سرویس ایجاد کنید و بدون تغییر در سرویس دیگری آن را دیپلوی کنید؟؟؟؟؟؟؟ 'سم نیومن'
در تعیین مرز های سرویس ها باید خیلی زیاد به resilience engineering دقت کنیم. تاب آوری سرویس ها بسیار مهم هستند. در نهایت باید به گونه ایی سرویس ها مدل سازی شده باشند که در صورت خراب شدن هرکدوم فقط یه بخش کوچک از پروژه خراب شده باشه و بقیه پروژه به کار خودشون ادامه بدن.
تصور کنید یه سیستم یکپارچه بزرگ دارید (monolithic) و میخاید یه تغییر روش اعمال کنید.
خب در ابتدا ده خط کد رو تغییر میدید و به عنوان ورژن اول تغییر اعمال میکنید.سپس یه بخش دیگه رو تغییر میدید و چندین تا تغییر روی هم انباشه میشه و یکجا دیپلوی میکنید.
سرویس رو ریستارت میکنید و بوم . . .
همه چیز داون میشه. چون یه اشتباهی در یکجا اتفاق افتاده که مربوط به یکی از ده تغییر قبلی شما بوده.
و الان کللللل پروژه داون شده. خب مسلما با سرعت هرچه تمام مشکل رو پیدا میکنید و حل میکنید و باز سرویس رو ران میکنید و احتمالا مشکل برطرف شده اما همچنان احتمال این وجود داره که در تلاش برای این مشکل یه مشکل دیکه بوجود آورده باشید. و حتی اگر مشکلی هم بوجود نیاورده باشید استرس وارد شده و ترس ایجاد شده از تغییر و اپدیت پروژه به خودی خود سرسام آور است. این مشکل رو در نظر داشته باشید و با درک این شرایط به طراحی معماری میکروسرویس خود بپردازید. چون اگر در طراحی و مدل سازی سرویس ها اشتباه کنید و یا اصول رو رعایت نکنید در واقع یه distributed monolithic میسازید که علاوه بر مشکلات معماری یکپارچه یه سری مشکلات دیگه اعم از پیچیدگی و نگهداری سخت رو هم بدنبال میاره.
ینی اگر در همون معماری مونولیت بمونید تا خرخره توی monolithic hell هستید و اگر وارد یه معماری میکروسرویس بد بشید از چاله دراومدید افتادی داخل چاه.
پس در تعیین مرزهای میکروسرویس ها و مدل سازی میکروسرویس ها و مشخص کردن api ها دقت کافی رو به خرج بدید.