مشخصات مقاله
-
0.0
-
1002
-
0
-
0
استفاده از Domain Analysis برای مدل میکروسرویس ها
یکی از بزرگترین چالشهایی که در میکروسرویس وجود دارد تعیین کردن حدود و مرزبندی سرویسهایی است که به صورت مستقل کار میکنند. رویکرد کلی برای انجام چنین کاری این است که هر سرویس باید تنها یک کار را انجام دهد. اما انجام چنین کاری تنها در تئوری بسیار بی نقص خود را نشان میدهد اما در عمل مشکلاتی را به وجود خواهد آورد. البته این موضوع را نیز باید گفت که ایجاد یک طراحی درست و کامل برای رسیدن به چنین موضوعی کار سادهای نبوده و یک روش کاملا مکانیکی و عملی برای این کار وجود ندارد. در ابتداییترین نقطه کار شما باید به صورت عمیق به دامنه کاری و منطقی اپلیکیشنتان فکر کنید، موارد لازم را مهیا سازید و در نهایت اهدافی را برای خودتان تعیین کنید. اگر چنین کاری را انجام ندهید در نهایت طراحی شما با مشکلات تکنیکی بسیار زیادی مواجه خواهد بود. مشکلاتی مانند مخفی شدن نیازمندیها و وابستگیها در بین سرویسها، رابط کاربری نامرتب و... . برای همین شما باید رویکرد متفاوتی را پیش بگیرید. هدف از این مقاله دقیقا این قضیه خواهد بود. در این مقاله ما قصد داریم رویکرد Domain-Driven برای طراحی میکروسرویسها را به شما معرفی کنیم.
در این مقاله ما تنها قصد ارائه یکسری توضیح را نخواهیم داشت و سعی میکنیم با مثال پیش برویم. مثالی که برای این مقاله در نظر گرفتهایم یک سرویس تحویل محصول با استفاده از پهپاد خواهد بود.
در این مقاله ما تنها قصد ارائه یکسری توضیح را نخواهیم داشت و سعی میکنیم با مثال پیش برویم. مثالی که برای این مقاله در نظر گرفتهایم یک سرویس تحویل محصول با استفاده از پهپاد خواهد بود.
مقدمه
میکروسرویسها باید براساس تواناییها و نیازمندیهای منطقی کسب و کارها شکل بگیرد و سراغی از لایههای افقی اپلیکیشن مانند پیامرسانی و دسترسی به داده را نگیرد. در کنار این سرویسها باید نهایت مستقل بودن خود را نشان داده و از کارایی بالایی برخوردار باشند. این موارد جزو کلیاتی است که باید در میکروسرویسها رعایت شود.
میکروسرویسها نیاز دارند که loosely coupled باشند. منظور از این عبارت این است که در یک سیستم اگر ما اجزاء مختلفی داشته باشیم این اجزاء باید در کمترین میزان وابستگی به همدیگر باشند تا سیستم به درستی کار بکند. اگر اجزاء مختلف یا سرویسهای متفاوت نیازمندی اجرایی بالایی به همدیگر داشته باشند میگوییم که این سیستم نرخ loosely coupled بالایی دارد. طراحی یک میکروسرویس باید به گونهای باشد که اگر در یک سرویس تغییراتی ایجاد میشود نیاز به بروزرسانی در دیگر سرویسها وجود نداشته باشد.
همچنین زمانی که در طراحی میکروسرویس هر سرویس به صورت جداگانه یک هدف مشخص و واضح داشته باشد میگوییم که این میکروسرویس جامع و منسجم است. برای مثال شما یک سرویس خواهید داشت که فقط کار مدیریت کاربران را انجام میدهد. اگر این سرویس در کارهای دیگر نیز دخالت داشته باشد در این حالت کلیت میکروسرویس ما از انسجام کافی برخوردار نخواهد بود.
همچنین یک میکروسرویس نیاز دارد که اطلاعات الگوریتمی خود را کپسولهسازی کرده و از دید کاربران مخفی بکند. برای مثال زمانی که یک پهپاد برای توزیع محصول یک کاربر اختصاص یافته کاربر نباید اطلاعات مربوط به چگونگی زمانبندی فرایند تخصیص این پهپاد را مشاهده بکند. به صورت کلی روند مدیریتی این کار باید از دید مشتری دور بماند.
Domain-driven design یا به اختصار DDD مناسبترین چهارچوبی است که شما را به اهداف گفته شده در این مقاله میرساند. در حال حاضر این چهارچوب نیز به عنوان مناسبترین روش برای پیادهسازی یک میکروسرویس شناخته میشود.
DDD دو فاز جداگانه در مسیر پیادهسازی را دارد:فاز استراتژی و فاز تاکتیک .
در فاز استراتژی شما باید ساختار بزرگ سیستم خود را تعریف کنید. هدف اصلی این فاز این است که شما بتوانید روی توانمندیهای منطقی و کسب و کار خود تمرکز داشته و روی اصول آن باقی بمانید.
فاز تاکتیک شامل یکسری الگوها و پترنهای طراحی است که به شما در جهت ایجاد مدل Domain کمک میکند. این الگوها شامل موجودیتها، تودهها و سرویسهای Domain است که در نهایت به شما در ساختن میکروسرویسهایی که هم منسجم هستند و هم به خوبی از یکدیگر استقلال دارند کمک میکند.
فاز استراتژی و فاز تاکتیک در DDD
در این مقاله و چند مورد بعدی در ارتباط با موضوعات زیر و اعمال کردن آنها روی اپلیکیشن تحویل محصول با استفاده از پهپاد صحبت خواهیم کرد:
- آنالیز منطق و اهداف کاری اپلیکیشن برای درک نیازمندیهای آن. خروجی این قسمت یک گزارش توضیحی از گستره کاری خواهد بود که در نهایت میتواند در تعیین و نتیجهگیری Domain Modelها مناسب باشد.
- در قدم بعدی ما bounded contextهای دامنهای که قصد داریم آن را ایجاد کنیم تعریف خواهیم کرد. هر bounded context شامل یک مدل از دامنه میشود که یک زیر دامنه بزرگتر از اپلیکیشن را نشان خواهد داد.
- در هر bounded context یک الگوی تکنیکی DDD را اعمال میکنیم تا موجودیتها، تودهها و سرویسهای Domain را تعریف کنیم.
- از نتایج حاصل آمده در قدم قبلی در جهت تعیین میکروسرویسهای داخل اپلیکیشن استفاده خواهیم کرد.
در این مقاله ما سه قدم اول لیست بالا را انجام خواهیم داد. در مقاله بعدی نیز سراغ قدم چهارم خواهیم رفت. البته این موضوع را در نظر داشته باشید که DDD یک پروسه تکرار شونده و در فرایند انجام است. به همین دلیل یک کار انجام شدنی برای همیشه نیست و مدام باید به توسعه آن نگاه بیاندازید. سرویسها و حدودشان یک چیز ثابت نیستند زمانی که اپلیکیشن شما پیشرفت کند ممکن است همه چیز تغییر کرده و سرویسهای کوچکتری از یک سرویس دیگر ایجاد کنید. به همین دلیل است که این فرایند یک فرایند پایان ناپذیر به حساب میآید.
سناریو: اپلیکیشن تحویل محصول با استفاده از پهپاد
بیایید تصور کنیم یک شرکت قرار است یک سرویس تحویل محصول با استفاده از پهپاد را راه اندازی کند. این شرکت یک ناوگان کامل از پهپاد را در اختیار دارد. مشتریان در این سرویس محصولاتی که میخواهند را میتوانند با استفاده از پهپاد دریافت کنند. برای اینکار باید درخواست خود را ارائه دهند. زمانی که یک مشتری یک درخواست را ارسال کند، سیستم Back-End یک پهپاد را به این کار تخصیص داده و مدت زمان تقریبی تحویل کالا را به مشتری نشان میدهد. زمانی که پهپاد مشغول انجام کار خود است، مشتری نیز میتواند موقعیت مکانی پهپاد را مشاهده کرده و ببیند که دقیقا این پهپاد در کجا است.
سناریویی که در مواجهه با این شرکت با آن روبرو هستیم گستردگی پیچیدهای دارد. تنها برخی از وظایف مهندسین این اپلیکیشن پیادهسازی یک سیستم زمانبندی برای پهپادها، پیادهسازی رهگیری بلادرنگ کالاها، مدیریت کاربران، ذخیره و آنالیز دادهها و نگهداری تاریخچه آنهاست. این تنها بخشی از کار است چرا که شرکت قصد دارد کاربردهای این اپلیکیشن را افزایش داده تا در نهایت بتواند بازار خوبی را در اختیار بگیرد. از این رو دامنه کاری این اپلیکیشن گسترش پیدا کرده و در گذر زمان بزرگ تر میشود.
این اپلیکیشن نیاز دارد که در مقیاس ابر یا Cloud-Scale عملیاتی شود و همچنین ویژگیهای SLO یا High Service Level Objective را رعایت کند. شرکتی که قصد پیادهسازی این سرویس را دارد همچنین در نظر دارد تا قسمتهای مختلف اپلیکیشن دارای مکان ذخیرهسازی و کوئری گیری منحصر به فرد خود باشند. به همین دلیل در نهایت مهندسین این شرکت تصمیم میگیرند تا از معماری میکروسرویس استفاده کنند.
آنالیز Domain
با استفاده از رویکرد DDD شما میتوانید میکروسرویس خود را به شیوهای طراحی کنید که تمام نیازهای فانکشنال و رویکردی شما را دنبال کند. استفاده از این رویکرد میتواند محدودیتهای موجود در دیگر الگوها را از سر راه شما برداشته و به بهترین شکل در پیادهسازی میکروسرویس به شما کمک بکند.
قبل از اینکه سراغ هر گونه کدنویسی بروید بهتر است یک دید جامع و کامل روی سیستمی که در حال ایجاد آن هستید داشته باشید. رویکرد DDD با مدلنویسی بخش کسب و کار و کاربرد کلی اپلیکیشن کار را شروع میکند و سپس سراغ ایجاد Domain Model خواهد رفت. منظور از Domain Model یک مدل کلی یا انتزاعی از همان گستره کاری اپلیکیشن است. با استفاده از این حالت شما میتوانید یک دید کلی از اپلیکیشن را در اختیار توسعه دهندگان و برنامه نویسان پروژه بگذارید. در نتیجه اولین قدم شما برای این مسئله انجام کار مدلنویسی خواهد بود.
این کار را با نقشهکشی و دیاگرام درست کردن شروع کنید. در دیاگرامی که درست میکنید تمام کارکردهای اپلیکیشن همراه با ارتباطاتشان با دیگر بخشها را ترسیم کنید. البته انجام این کار یک کار تیمی بین افراد مختلف مانند مهندسین نرم افزار، متخصصین حوزه میکروسرویس و... خواهد بود. شما نیازی به هیچ پیچیدگی خاصی ندارید تنها کاری که باید بکنید این است که از یک وایت برد یا یک ابزار رسم دیاگرام استفاده کنید.
همزمان با ایجاد دیاگرام و کشیدن نقشه کلی اپلیکیشن، برخی از سرویسهایی که جایگاهشان برایتان غیر قابل درک بود، واضحتر میشوند. برای مثال کدام سرویس مربوط به کدام سرویس دیگر است و چه سرویسی زیر مجموعه سرویس دیگر خواهد بود. در این قسمت از کار نیازی نیست نگران اینکه چه قسمتی را با چه تکنولوژی پیادهسازی کنید ندارید. در نتیجه فعلا تمرکزتان را روی این موضوع نگذارید. همچنین به عنوان یک نکته مهم، آن دسته از سیستمهایی که نیاز دارند با سیستمهای خارجی مانند یک درگاه پرداخت ارتباط برقرار کنند را مشخص کنید.
مثال: اپلیکیشن تحویل محصول با استفاده از پهپاد
بعد از انجام آنالیزها و بررسیهای گستردگی اپلیکیشن، شرکت توسعه دهنده و تیم آن به یک طرح کلی از اپلیکیشنشان رسیدند. در زیر میتوانید دیاگرام این اپلیکیشن را مشاهده کنید:
اپلیکیشن تحویل محصول با استفاده از پهپاد
همانطور که در تصویر بالا مشاهده میکنید هر قسمت جدای از آنکه استقلال کارکردی دارد به سرویسهای دیگر متصل است. برای آشنایی بیشتر با قسمتهای مختلف این اپلیکیشن بیایید با این موارد آشنا شویم:
- Shipping عنوانیست که در مرکز دیاگرام قرار گرفته است، دلیل آن نیز واضح است چرا که هسته اصلی کسب و کار را تشکیل میدهد. هر آنچه که در این دیاگرام قرار دارد برای فعال سازی و درست کار کردن این قسمت است.
- Drone management هم قسمت مهمی از این دیاگرام و کارکرد کلی اپلیکیشن است. همانطور که مشاهده میکنید یکسری سرویس دیگر به این قسمت متصل بوده که هدف آنها کارکرد درست Drone Management است. برای مثال drone repair بخشیست که تعمیرات و اختلالات پهپادها را بررسی میکند.
- ETA Analysis سرویس مهم دیگری است که زمان تقریبی انجام شدن درخواستها را بررسی میکند.
- Third-party transportation سرویس دیگری است که حالتهای دیگر تحویل بستهها را تنظیم میکند. در صورتی که یک پهپاد نتواند یک بسته را ارسال کند، این سرویس فعال خواهد شد.
- Drone Sharing یکی از ویژگیهاییست که ممکن است در آینده به عنوان یکی از اصلیترین کاربردهای این اپلیکیشن عرضه شود. این سرویس در نسخههای ابتدایی قرار نخواهد گرفت. فلسفه سرویس این است که اگر پهپادهای اضافی موجود بودند بتوانیم آنها را به صورت اجارهای در ساعاتی خاص در اختیار کاربران قرار دهیم.
- Video surveillance یا نظارت ویدیویی سرویس دیگری است که در صورت بزرگ شدن اپلیکیشن، در نسخههای بعدی آن عرضه میشود.
- User accounts، Invoicing و Call Center تماما سرویسهایی هستند که در زیر مجموعه سرویس پشتیبانی کار خواهند کرد.
این قضیه را در نظر داشته باشید که ما هنوز در ارتباط با اینکه از چه تکنولوژیها و ابزارهایی برای پیادهسازی این سرویسها استفاده کنیم تصمیم نگرفتهایم. برخی از این سرویسها نیز ممکن است به سرویسهای خارج از شرکت شروع به فعالیت کنند و ما آنها را برونسپاری کنیم. در نظر داشته باشید که حتی این دسته از سرویسها باید در مدل طراحی شده قرار بگیرند چرا که بخشی از کلیت اپلیکیشن هستند. به عنوان یک نکته مهم این موضوع را در نظر داشته باشید که هر گاه از یک سرویس خارجی استفاده میکنید ممکن است رویکردهای مهندسی نرم افزار آنها با اپلیکیشن شما کاملا متفاوت باشند. از این جهت مراقب ارتباط برقرار کردن این سرویسها با سرویسهای داخلی باشید.
تعریف bounded contextها
مدلی که تا به حال از اپلیکیشن ایجاد کردیم شامل موارد واقعی هستند که در دنیا وجود دارند: کاربران، پهپادها، بستهها و... . اما این بدان معنا نیست که هر قسمت از اپلیکیشن باید اطلاعات کاملی از هر کدام اینها ارائه دهد.
برای مثال زیر سیستمهایی که تعمیرات پهپادها و پیشبینی زمان رسیدن آنها را ارائه میدهند باید بسیاری از خصوصیات فیزیکی هر کدام از دستگاهها را در خود ذخیره کنند. تاریخچه تعمیرات، میزان مسافت طی شده، شماره مدل، کارایی و... . اما برای سرویس «زمانبندی ارسال» ما به هیچ کدام از این موضوعات اهمیت نمیدهیم، با این حال نیاز داریم که با پهپادها نیز ارتباط برقرار کنیم. تنها وظیفه این سرویس آن است که ببیند آیا یک پهپاد موجود است یا خیر.
اگر ما یک مدل را برای هر دو زیر سیستمها تعریف کنیم پیچیدگی برنامه به صورت غیر لازمی افزایش پیدا میکند. همچنین با هر تغییری که در یکی از این سیستمها اتفاق میافتد، ایجاد تغییر در هر دو بسیار سخت خواهد شد. از این جهت همواره به یاد داشته باشید که حتی اگر سیستمهای مختلف با موجودیتهای یکسانی در ارتباط هستند از مدلهای مختلفی تشکیل شده و طراحی مجزایی داشته باشند.
به همین دلیل است که محتوا و ویژگیهای داخل هر سرویس باید محدود به کاری شوند که ارائه میدهند. در دنیای معماری DDD ما به این موضوع bounded contexts میگوییم. میتوانیم به فارسی آنها را زمینههای محدود شده بنامیم.
یک زمینه محدود شده به محدودیتها و مرزبندیهایی گفته میشود که در یک Domain اعمال میشود. براساس دیاگرامی که تا به اینجا کار در اختیار داریم ما میتوانیم براساس کاربرد هر کدام از سرویسها آنها را در مفهوم bounded contexts بگنجانیم.
bounded contexts
زمینههای محدود شده لزوما از یکدیگر ایزوله نیستند. همانطور که در تصویر بالا مشاهده میکنید خطوط پر رنگ مشکی نمایانگر ارتباط میان دو سرویس هستند که هر دو محدود شده اما در نهایت با همدیگر ارتباط دارند و ایزوله نیستند. برای مثال Shipping با Accounts ارتباط دارد چرا که دریافت اطلاعات مشتریان در گرو این ارتباط است.
در مقاله بعدی
بعد از آنکه آنالیزهای لازم برای Domain را انجام دادیم حال نوبت به قسمت تکنیکی ماجراست. در مقاله بعدی سراغ مفهوم Tactical DDD خواهیم رفت.