خانه / microservices / چگونه یک سیستم یک-تکه(مانولیت) به مایکروسرویس ها شکسته می شود

چگونه یک سیستم یک-تکه(مانولیت) به مایکروسرویس ها شکسته می شود

متن زیر ترجمه مقاله ژامک دهقانی است که در این آدرس پابلیش شده است.

 

چگونه یک سیستم یک-تکه(مانولیت) به مایکروسرویس ها (مجموعه ای سرویس های کوچک متسقل(مترجم)) شکسته می شود

چه چیزی را و چه موقع باید جدا کرد؟
با بزرگ شدن بیش از حد سیستم های یک تکه جهت سر و کله زدن با آنها؛ بسیاری از سازمان ها تصمیم می گیرند که آنها را به روش معماری مایکروسرویس ها خرد کنند. این یک سفر ارزشمند است اما آسان نیست. ما متوجه شدیم برای اینکه این سفر را بخوبی انجام دهیم؛ باید با یک سرویس ساده شروع کنیم؛ اما سپس سرویس هایی را که بر اساس استعدادهای(Capability) عمودی برای بیزینس دارای اهمیت است و تغییرات زیادی بر روی آنها رخ می دهد را بیرون می کشیم. این سرویس ها باید در ابتدا بزرگ باشند و ترجیحا به باقیمانده سیستم یک تکه موجود وابسته نباشند. باید مطمئن شویم که هر مرحله از مهاجرت و انتقال یک بهبود مستقل و اتومیک به معماری کلی را نمایش می دهد.
مهاجرت از یک سیستم یک-تکه به یک اکوسیستم از مایکروسرویس ها یک سفر حماسی و بزرگ است. کسی که در این سفر گام بر می دارد دارای امیدواری هایی ست از جمله افزایش مقیاس عملیاتی؛ بیشتر شدن سرعت اعمال تغییرات و همچنین از بین بردن هزینه تغییرات. آنها می خواهند که تعداد تیم های خود را در حالیکه این قابلیت را به آنها می دهد که بصورت موازی و مستقل از دیگر تیم ها ارزش را تحویل دهند؛ افزایش دهند. آنها می خواهند که هر چه سریعتر با استعدادها و توانایی های اصلی و مرکزی بیزینس خود تجربه کسب کنند و سریعتر ارزش را تحویل دهند. آنها همچنین می خواهند که هزینه ی بالای اعمال تغییر به سیستم های یک-تکه ی خود را نیز از بین ببرند.
تصمیم گیری در مورد اینکه چه استعداد هایی باید تفکیک شوند، چه موقع و به چه صورت باید بصورت تدریجی مهاجرت کنند، برخی از چالش های تجریه یک سیستم یک-تکه به یک اکوسیستم از مایکروسرویس ها است. در این مقاله؛ من یک سری تکنیک که می تواند به تیم های انتقال – توسعه دهنده ها؛ معمارها؛ مدیران تکنیکال- در گرفتن این تصمیم ها در حین سفر کمک کند را ارائه می دهم.
جهت روشن شدن تکنیک ها؛ از یک برنامه خرده فروشی آنلاین چند لایه ای(به عنوان مثال) استفاده می کنم. این برنامه رابط گرافیکی کاربر؛ قوانین بیزینسی و لایه های دیتا را در هم تنیده است. دلیلی که این مثال را انتخاب کردم این است که معماری این برنامه دارای ویژگی های برنامه های یک-تکه ای است که بسیاری از بیزینس ها اجرا کرده اند و پشته ی تکنولوژی آن به اندازه ی مدرن است که تصمیم درباره تجزیه آن را به جای نوشتن مجدد و جایگزینی کامل توجیه کند.
مقصد اکوسیستم مایکروسرویس ها
قبل از شروع سفر، ضروری است که همه افراد درک مشترکی از یک اکوسیستم مایکروسرویس ها داشته باشند. اکوسیستم مایکروسرویس ها یک پلت فرمی از سرویس هاست که هر سرویس یک استعداد و توانایی بیزینس را پوشش می دهد. یک استعداد بیزینس چیزی که یک بیزینس در یک دامنه ی خاص برای انجام دادن اهداف و مسئولیت هایش انجام می دهد را نمایش می دهد. هر مایکروسرویس یک API را ارائه می دهد که توسعه دهنده ها می توانند به آن دسترسی داشته و بصورت خودمختار از آن استفاده کنند. مایکروسرویس ها دارای حیات مستقل هستند. توسعه دهنده ها می توانند هر سرویس را بصورت مستقل بسازند آن را تست کرده و در نهایت منتشر کنند. اکوسیستم مایکروسرویس ها یک ساختار سازمانی از تیم های دائمی مستقل که هر تیم مسئول یک یا چند سرویس است را تاکید می کند. برخلاف درک عمومی و “مایکرو” در عبارت مایکروسرویس؛ اندازه هر سرویس کمتر اهمیت دارد و ممکن به سطح پختگی عملیاتی سازمان ها بسیار وابسته باشد. همانطور که مارتین فاولر اشاره کرد “مایکروسرویس ها یک برچسب است نه یک توصیف”.
اکوسیستم مایکروسرویس ها


تصویر 1: سرویس ها توانایی و استعدادهای بیزینس رو پوشش می دهند؛ و دیتا و عملیات را از طریق API خود ارائه می دهند

 

راهنمای سفر
قبل از عمیق شدن در راهنما، مهم است که بدانیم یک هزینه سربار زیاد مرتبط با تجزیه یک سیستم موجود به مایکروسرویس ها وجود دارد و ممکن است چندین تکرار(اسپرینت در واژگان اسکرام –مترجم)) طول بکشد. برای توسعه دهندگان و معماران ضروری است با دقت محاسبه کنند که آیا تجزیه یک سیستم یک-تکه فعلی یک مسیر درست است، و آیا خود مایکروسرویس ها یک مقصد مناسب است؟ پس از این شفاف سازی، اجازه بدید برویم سراغ راهنما.
با یک استعداد ساده و کاملا جدا شروع به گرم کردن کنید
راه اندازی یک مسیر مایکروسرویس ها نیازمند یک سطح آمادگی عملیاتی است. این سطح آمادگی نیازمند دسترسی بر اساس نیاز به محیط عملیاتی، ایجاد انواع چرخه های انتشار جدید جهت ایجاد، تست، و انتشار سرویس های قابل اجرا بصورت مستقل و توانایی جهت ایمن سازی، اشکال یابی و مانیتور کردن معماری توزیع شده است. عملیاتی چه سرویس ها را از ابتدا به ساکن توسعه دهیم و چه یک سیستم فعلی را تجزیه کنیم بلوغ آمادگی نیاز می باشد. جهت اطلاعات بیشتر در مورد این سطح آمادگی عملیاتی مقاله ی پیش نیازهای مایکروسرویس های مارتین فاولر را مشاهده کنید. خبر های خوب این است که از زمان انتشار مقاله ی مارتین، تکنولوژی عملیاتی مایکروسرویس ها به سرعت رشد پیدا کرده است. این پیشرفت ها شامل Service Mesh، یک لایه زیرساخت اختصاصی جهت اجرای سریع؛ قابل اعتماد و مطمئن شبکه ای از مایکروسرویس ها؛ سیستم های container orchestration برای آماده سازی یک سطح انتزاع بیشتر و بالاتر از زیر ساخت انتشار و تکامل سیستم های انتشار مداوم از جمله GoCD جهت ایجاد، تست و انتشار مایکروسرویس ها به عنوان کانتینرها می باشد.
پیشنهاد من برای توسعه دهندگان و تیم های عملیاتی این است که با اولین یا دومین سرویس که تجزیه می کنند یا بصورت سرویس های جدید می سازند زیر ساخت های بالا ، چرخه های انتشار مداوم و سیستم های مدیریت API را برپا کنند. با استعداد بیزینسی شروع کنید که مشخصا از سیستم یک-تکه جدا است؛ آنها نیاز به تغییرات زیاد در برنامه های های رابط گرافیکی که در حال حاضر از سیستم یک-تکه استفاده می کنند ندارند و احتمالا نیاز به محلی برای ذخیره دیتا هم نیستند. چیزی که تیم های تحویل در اینجا نسبت به آن بهینه می شوند این است که رویکردهای انتشار را اعتبار سنجی می کنند، مهارت های اعضای تیم را بالا می برند، و حداقل زیر ساخت مورد نیاز برای انتشار مستقل سرویس قابل انتشار که API خود را ارائه کرده است را بر پا می کنند. به عنوان یک مثال، برای یک برنامه ی خرید و فروش آنلاین، اولین سرویس می تواند سرویس “اعتبار سنجی end user” باشد، سرویسی که برنامه یک-تکه می تواند جهت اعتبار سنجی کاربران آن را صدا بزند. و سرویس دوم می تواند “سرویس پروفایل کاربر” باشد یک سرویس facade که یک نمایش مناسب تر از مشتریان برای کلاینت های جدید برنامه ها مهیا می کند.
ابتدا پیشنهاد می کنم که سرویس های ساده ی مرزی را تجزیه کنید. سپس ما یک رویکرد متفاوت جهت تجزیه و جدا کردن استعدادهایی که در سیستم یک-تکه جایگزین شده اند را به دست آورده ایم. من توصیه می کنم که ابتدا سرویس های مرزی را انجام دهید زیرا در ابتدای مسیر و سفر، بیشترین ریسک و خطر تیم انتشار محصول این است که ممکن است در عملیاتی کردن مایکروسرویس ها شکست بخورند. بهمین دلیل بهتر است جهت تمرین پیش نیازهای عملیاتی که مایکرورویس ها طلب می کند از سرویس های مرزی استفاده کرد. به محض اینکه تیم عملیاتی و انتشار محصول؛ این نیازمندی را مرتفع کرد؛ آنها می توانند مشکل کلیدی تفکیک و جداسازی سیستم یک-تکه را حل کنند.

تصویر 2: با یک استعداد که دارای شعاع تغییر کم است برای مهیا کردن نیازمندی های عملیاتی شروع به گرم کردن کنید

وابستگی به برنامه یک-تکه را کاهش دهید
به عنوان یک اصل اساسی تیم های انتقال و استقرار نیاز دارند که وابستگی های مایکروسرویس های تازه شکل گرفته به برنامه یک-تکه را کاهش دهند. یکی از مزیت های اصلی مایکروسرویس ها داشتن یک چرخه ی انتشار متسقل و غیر وابسته و سریع است. داشتن وابستگی به برنامه یک-تکه-دیتا، منطق، APIها- سرویس را به چرخه انتشار برنامه یک-تکه وابسته می کند و بر سر راه مزیت ذکر شده مانع تراشی می کند. غالبا انگیزه اصلی برای دور نگه داشتن سرویس از برنامه یک-تکه هزنیه ی بالا و سرعت پایین تغییر استعدادهای بیزینس است که در برنامه یک-تکه قفل شده است، در نتیجه می خواهیم که بشدت به سمتی حرکت کنیم که این سرویس های اصلی و پایه ای(core services) را از یکدیگر تجزیه کند. در صورتی که تیم ها همزمان که استعدادهای بیزینس را درون سرویس های خود ایجاد می کنند، این راهنما را دنبال کنند، در عوض چیزی که بدست می آورند تغییر مسیر وابستگی از برنامه یک-تکه به سرویس ها است. از انجایی که این مسیر وابستگی سرعت تغییر سرویس های جدید را آهسته نمی کند؛ این یک مسیر وابستگی قابل قبول است.
یک خرده فروشی آنلاین که “خرید” و “تبلیغات” قابلیت های اصلی آن هستند را در نظر بگیرید، “خرید” از “تبلیغات” در حین بررسی فرآیند پیشنهاد بهترین تبلیغات به مشتریانی که واجد شرایط آن تبلیغات جهت خرید اقلام موجود در تبلیغ هستند استفاده می کند. اگر بخواهیم تصمیم بگیریم که کدام یک از دو توانایی بیزینس باید تجزیه و جدا شود، پیشنهاد من این است که ابتدا با جدا کردن “تبلیغات” شروع کنید و سپس سراغ “خرید” بروید. چون به این طریق ما وابستگی به برنامه یک-تکه را کاهش می دهیم. در این روش اگر ابتدا از “خرید” شروع کنیم همچنان سرویس جدید جدا شده یعنی “خرید” بر روی برنامه یک-تکه قفل است چون هنوز یک وابستگی به مایکروسرویس “تبلیغات” وجود دارد.
دستورالعمل های بعدی راه های دیگری برای تصمیم گیری در مورد ترتیبی که توسعه دهنده ها باید سرویس های را جدا و تجزیه کنند پیشنهاد می دهد. این بدین معنا است که ممکن است همیشه قادر نباشند که از وابستگی های برگشتی به برنامه یک-تکه را اجتناب کنند. در مواردی که سرویس های جدید در نهایت برنامه یک-تکه را صدا می زنند؛ پیشنهاد می کنم که در برنامه یک-تکه API جدید ارائه شده، و دسترسی به API به کمک لایه anti-corruption در سرویس جدید انجام شود تا اطمینان حاصل شود که مفاهیم برنامه یک-تکه به بیرون درز پیدا نکرده است. تلاش کنید که API ارائه کنید که مفاهیم و ساختار خوش تعریف دامین را ارائه می دهد حتی اگر پیاده سازی داخلی برنامه یک-تکه به شکل مناسبی پیاده سازی نشده باشد. در این مورد تاسف بار تیم های انتشار هزینه و سختی تغییر برنامه یک-تکه، تست کردن و انتشار سرویس های جدیدی که به انتشار برنامه یک-تکه وابسته هستند، را تحمل خواهند کرد.


شکل 3 : ابتدا سرویس که نیاز به وابستگی برگشتی به برنامه یک-تکه ندارد را جدا کنید و تغییرات در برنامه یک-تکه را کاهش دهید

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

شکل 4: مفاهیمی که بیشترین اتصال را دارند شناسایی کنید و آنها را تفکیک، مجددا ایجاد کرده و به درون سرویس های دامنه مشخص ببرید

از ابزارهای تحلیل وابستگی و ساختار کد از جمله Structure 101 جهت شناسایی استعداد های بیزینسی کلیدی که در برنامه یک-تکه بیشترین وابستگی و محدودیت را دارند استفاده کنید.

بصورت عمودی تفکیک کنید و ابتدا دیتا را منتشر کنید
محرک اصلی برای جدا سازی قابلیت های بیزینسی به خارج از برنامه یک-تکه این است که بتوانیم آنها را بصورت مستقل از همدیگر منتشر کنیم. این اصل اولیه باید هر تصمیمی که توسعه دهنده ها درباره ی اینکه به چه صورت باید تجزیه را انجام دهند کمک کند. یک سیستم یک-تکه غالبا تشکیل شده است از لایه های بهم چسبیده یا حتی سیستم هایی که نیاز است با هم منتشر شوند و دارای وابستگی شکننده هستند. به عنوان مثال در سیستم خرده فروشی آنلاین، سیستم یک-پارچه شامل یک یا چندتا برنامه ی کاربردی جهت تعامل مشتری، یک سیستم بک اند که بسیاری از قابلیت های بیزیسی را پیاده سازی کرده است با یک محل ذخیره دیتا یکپارچه جهت نگهداری وضعیت می باشد.
بیشتر تلاش های تجزیه با تفکیک کردن مولفه های ارتباط کاربر و یکسری سرویس های facade جهت مهیا کردن API های توسعه دهنده پسند برای UI های مدرن شروع می شوند، در حالیکه دیتا هنوز در یک اسکیما و محل ذخیره نگه داشته می شود. در نتیجه این رویکرد یکسری بردها را نتیجه می دهد از جمله تغییرات سریعتر در UI، وقتی به استعداد های اصلی می رسد تیم تحویل نهایتا می تواند با سرعت آهسته ترین بخش، سیستم یک-تکه و دیتابیس یک تکه، حرکت کند، به زبان ساده، بدون تفکیک و تجزیه دیتا، معماری، معماری مایکروسرویس ها نیست. نگه داری تمامی دیتا ها در یک دیتابیس با ویژگی مدیریت غیر متمرکز دیتا مایکروسرویس ها در تضاد است.
استراتژی این است که استعدادهای بیزینس را بصورت عمودی حرکت دهید، استعدادهای اصلی با دیتا های آن را تفکیک کنید و تمام برنامه های فرانت اند را به APIهای جدید هدایت کنید.
داشتن چندین برنامه که درون یک دیتای مشترک می نویسند یا از آن می خوانند مهمترین عامل بازدارنده ی تفکیک دیتا ها بین سرویس هاست. تیم های انتقال نیاز دارند که با استراتژی های مهاجرت دیتا که بر اساس محیط آنها بسته به اینکه آیا آنها می توانند تمامی خواننده ها/نویسنده های دیتا را همزمان هدایت و مهاجرت کنند یا خیر را ترکیب کنند. استراتژی چهار مرحله ای مهاجرت دیتا Stripe یکی از استراتژی هایی است که به محیط های بسیاری که در حالیکه تمام سیستم تحت تغییر نیاز به اجرای مداوم دارد، نیازمند مهاجرت تدریجی برنامه هایی که از طریق دیتابیس یکپارچه شده اند اعمال می شود.

شکل 5: استعداد بیزینس را به همراه دیتاهایش به یک مایکروسرویسی که اینترفیس جدید را ارائه می دهد تفکیک کنید، و سپس استفاده کننده ها را به API جدید تغییر و هدایت کنید

از ضد الگوی فقط تفکیک façade ها، فقط تفکیک سرویس بک اند و عدم تفکیک دیتا بپرهیزید.

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

شکل 6: استعدادی که بیشترین اهمیت دارد، و بیشترین ارزش را برای بیزینس و مشتری ایجاد می کند و در عین حال مکررا تغییر می کند، را شناسایی و تفکیک کنید

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

 

استعداد بیزینس را تفکیک کنید نه کد را
وقتی که توسعه دهندگان تصمیم داشته باشند که یک سرویس را از یک سیستم موجود استخراج کنند، دو راه پیش روی دارند، تفکیک کد یا نوشتن مجدد استعداد بیزینس.
غالبا تفکیک سرویس یا تجریه برنامه یک-تکه به عنوان استفاده مجدد از پیاده سازی موجود و تفکیک آن به درون سرویس های جداگانه تصور می شود. این عمل تقریبا به این دلیل است که ما یک ادراک و شناخت متعصابه نسبت به کدی که آن را طراحی و نوشته ایم داریم. ایجاد کردن صرفنظر از اینکه چه اندازه فرآیند سخت است و نتیجه غیر کامل، باعث می شود که نسبت به آن علاقه بیشتری داشته باشیم. این در واقع به عنوان اثر IKEA شناخته می شود. متاسفانه این تعصب، تلاش برای تجزیه برنامه یک-تکه را عقب نگه خواهد داشت. این منجر به این می شود که توسعه دهنده ها و مهمتر مدیران تکنیکال هزینه ی بالا و ارزش پایین تجریه و استفاده مجدد از کد را نادیده بگیرند.
متناوبا تیم های تحویل دارای انتخاب نوشتن مجدد استعداد بیزینسی و کنار گذاشتن کد قدیمی هستند. نوشتن مجدد این امکان را به انها می دهد که استعداد بیزینس را مجددا بازبینی کنند، یک تعامل با بیزینس را شروع کنند تا فرآیندهای قدیمی و فرضیات و محدودیت های قدیمی که در گذر زمان در سیستم ایجاد شدند، را ساده سازی کنند. دوباره نویسی هم چنین فرصتی برای تازه سازی تکنولوژی، پیاده سازی کردن سرویس جدید با زبان برنامه نویسی و پشته ی تکنولوژی جدید که برای آن سرویس خاص مناسب تر است را نیز بدست می دهد.
به عنوان مثال در سیستم خرده فروشی، استعداد “قیمت گذاری و تبلیغ” یک بخش فکری پیچیده از کد است. این بخش تنطیمات داینامیک و برنامه قیمت گذاری و سیاست های تبلیغات را ممکن می سازد، تخفیف ها و پیشنهادها را بر روی طیف وسیعی از پارامترها شامل رفتار مشتری، وفاداری، بسته بندی محصول و … ممکن می سازد.
این استعداد مسلما یک کاندید خوب برای استفاده مجدد و تفکیک است. در عوض “پروفایل مشتری” یک استعداد CRUD ساده است که بیشتر شامل کدهای بویلیرپلیت برای serialization و کنترل کردن ذخیره دیتا و تنظیمات است، در نتیجه یک کاندید مناسب برای نوشتن مجدد و کنار گذاشتن کد فعلی است.
در تجربه ی من، در بیشتر سناریوهای تجزیه، تیم ها در نوشتن مجدد استعداد به عنوان یک سرویس جدید و کنار گذاشتن کد قدیمی عملکرد بهتری داشتند. در زیر هزینه ی بالای و ارزش پایین استفاده مجدد از کد را با آوردن دلایل بیان می شود:
• مقدار زیادی کد بویلرپلیت وجود دارد که با وابستگی های محیطی از جمله دسترسی به تنظیمات برنامه در زمان اجرا، دسترسی به محل ذخیره سازی دیتا ها در ارتباط هستند و با فریمورک ها توسعه داده شده اند. بیشتر این کدهای بویلرپلیت نیاز است که مجدد نوشته شوند. زیر ساخت جدید برای میزبانی یک مایکروسرویس نسبت به برنامه های زمان اجرای خیلی قدیمی بسیار متفاوت است، و نیازمند نوع کدهای بویلرپلیت کاملا متفاوت است.
• بسیار محتمل است که استعدادهای جدید حول مفاهیم کاملا شفاف دامین توسعه داده نشده اند. این منجر به انتقال و ذخیره سازی ساختارهای داده ای می شود که مدل های جدید دامین را منعکس نمی کنند و نیاز به بازسازی و تغییرات عظیم دارند.
• یک کد قدیمی و به ارث رسیده طویل که از تعداد زیادی تکرارهای تغییرات عبور کرده است، ممکن است شامل سطح بالایی از کد سمی بوده و ارزش کمی برای استفاده مجدد داشته باشد.
مگر اینکه استعداد مرتبط بوده، با یک مفهوم دامنه روشن و واضح هم تراز بوده و دارای یک ویژگی با درجه ی بالایی از فکر باشد، در غیر اینصورت پیشنهاد می کنم که مجدد نوشته شود و کد قدیمی کنار گذاشته شود.

شکل 7: کد با ارزش بالا و سم کم را مجدد استفاده و تفکیک کنید، کد با ارزش کم و دارای سم را بازنویسی کنید و کد قدیمی را کنار بگذارید

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

ابتدا ماکرو(بزرگ) بروید، سپس میکرو(کوچک)
یافتن مرزهای دامنه در یک سیستم یک-تکه به ارث رسیده هم هنر است و هم دانش. به عنوان یک قاعده عمومی تکنیک domain driven design را جهت یافتن bounded context هایی که مرزهای مایکروسرویس ها را تعریف می کنند یک محل خوب برای شروع است. اعتراف می کنم بسیار زیاد یک تصیح بیش از حد از برنامه یک-تکه بزرگ به سرویس های واقعا کوچک، سرویس های واقعا کوچک که طراحی آنها با نرمال سازی view دیتاهای موجود مشتق شده بود را مشاهده کردم. این رویکرد برای شناسایی مرزهای سرویس تقریبا همیشه منجر به انفجار کامبرین تعداد زیادی سرویس های anemic برای منابع CRUD می شود. برای بسیاری که نسبت به معماری مایکروسرویس ها جدید هستند این یک محیط با اصطکاک بالا ایجاد می کند که در نهایت تست انتشارهای مستقل و اجرای سرویس ها با شکست مواجه می شود. این یک سیستم توزیع شده ایجاد می کند که اشکال زدایی آن سخت است، یک سیستم توزیع شده که به مرزهای تراکنش ها شکسته می شود و در نتیجه حفظ یکپارچگی آن مشکل است، یک سیستم که بیش از حد برای سطح پختگی عملیاتی سازمان پیچیده است. هرچند برخی اکتشافات در مورد اینکه یک مایکروسرویس تا چه اندازه باید “مایکرو” باشد، اندازه تیم، زمان برای نوشتن مجدد سرویس، مقدار رفتارهایی که باید پوشش دهد و … وجود دارد. توصیه من این است که اندازه بستگی به تعداد سرویس هایی دارد که تیم های عملیاتی و انتشار می توانند بصورت مستقل منتشر، مانیتور و عملیاتی کنند. با سرویس های بزرگتر اطراف یک مفهوم منطقی دامنه شروع کنید، و سپس سرویس را به چندین سرویس هنگامی که تیم های عملیاتی آماده بودند بشکنید.
به عنوان مثال، در سفر تجزیه کردن سیستم خرده فروشی، توسعه دهنده های ممکن است با سرویس “خرید” که هم محتوای “کیف خرید” و هم خرید کیف را پوشش می دهد شروع کنند، به عبارت دیگر “چک کردن”. به محض اینکه توانایی آنها برای تشکیل تیم های کوچک و انتشار تعداد بیشتر سرویس ها بهبود یافت آنها می توانند “کیف خرید” را از “چک کردن” تفکیک و به سرویس جدید ببرند.

شکل 8: سرویس ماکرو را بر اساس مفاهیم دامنه تجزیه کنید و وقتی آماده بودید، سرویس ها را به مفاهیم دامنه کوچک تر بشکنید.

از مدل تکاملی ریچاردسون L3 و هایپرلینک ها جهت فعال کردن تجزیه های آتی سرویس ها بدون تاثیر گذاتشن بر صدا کننده سرویس استفاده کنید، به عبارت دیگر صدا زننده کشف می کند که چگونگی چک کردن را می داند ولی از جزئیات نا آگاه است

با گام های تکاملی و اتمیک و غیر قابل تغییر مهاجرت کنید

ایده ی کنار گذاشتن کامل یک سیستم یک-تکه به ارث رسیده با تجزیه آن به مایکروسرویس هایی که به زیبایی طراحی شده اند تا حدودی افسانه است و طبیعتا غیر خوشایند. هر مهندس چاشنی زده ای می تواند داستانهایی از مهاجرت سیستم های قدیمی و تلاش های مدرن کردن که برنامه ریزی شده بود و با خوشبینی بیش از حد قبل از اتمام کار همراه بود و در بهترین حالت در یک نقطه به اندازه کافی خوب در زمان رها شده است را نقل کند. بدلیل کاندیدهای بزرگ تغییر برنامه های بلند مدت چنین تلاش هایی رها می شوند: برنامه دیگر بودجه مالی ندارد، سازمان توجه خود را به چیز دیگری معطوف کرده است یا رهبر پشتیبان کننده آن، شرکت را ترک کرده است. در نتیجه این واقعیت باید طراحی شود که چه رویکردی تیم ها برای سفر از سیستم یک –تکه با مایکروسرویس ها دارند. من این رویکرد را “مهاجرت در گام های اتومیک معماری تکاملی” می نامم، که هر گام مهاجرت باید معماری را به وضعیت نهایی نزدیک تر کند. هر واحد تکامل باید یک گام کوچک و قدم بزرگ اما اتومیک باشد، چه کامل شود چه در نهایت نادیده گرفته شود. این بخصوص وقتی که ما یک رویکرد تکراری و تدریجی را جهت بهبود معماری کلی و تفکیک سرویس ها انتخاب می کنیم. هر تکرار باید ما را به یک محل بهتر نسبت به معماری هدف ببرد. با استفاده از اصطلاح توابع fitness معماری تکاملی، تابع fitness معماری بعد از هر گام مهاجرت اتومیک باید یک ارزش نزدیک تر به معماری هدف را ایجاد کند.
اجازه دهید این نکته را با یک مثال نمایش دهم. فرض کنید هدف معماری مایکروسرویس افزایش سرعت توسعه دهنده ها برای تغییر سیستم کلی جهت تحویل ارزش است. تیم تصمیم می گیرد که اعتبار سنجی کاربران پایانی را به یک سرویس جدید مبتنی بر پروتوکل OAuth 2.0 منتقل کند. این سرویس جهت جایگزینی روشی که برنامه های کلاینت فعلی(معماری قدیمی) کاربران پایانی را اعتبار سنجی می کنند و همچنین معماری جدید مایکروسرویس کاربر پایانی را اعتبار سنجی می کند در نظر گرفته می شود. بگذارید این افزایش در تکامل را “معرفی سرویس Auth” بنامیم. یک روش برای معرفی سرویس جدید این است که با این گام ها پیش می رویم:
(1) ایجاد سرویس Auth، پیاده سازی پروتوکل OAuth 2.0
(2) افزودن یک مسیر اعتبار سنجی جدید در بک اند برنامه یک-تکه جهت صدا زدن سرویس Auth برای اعتبار سنجی کاربر پایانی که از طرف او در حال پردازش یک درخواست است
اگر تیم در اینجا توقف کند و وارد ایجاد سرویس ها یا ویژگی های دیگر شود، آنها معماری کلی را در یک وضعیت آنتروپی رها کرده اند. در این وضعیت دو راه برای اعتبار سنجی کاربر وجود دارد؛ مسیر مبتنی بر Auth 2.0 جدید، و مسیر قدیمی مبتنی بر password/session. در این مرحله تیم واقعا از هدف کلی خود که ایجاد تغییرات سریعتر بود دورتر می شود. هر توسعه دهنده ی جدید کد برنامه یک-تکه نیاز دارد که با دو مسیر کد دست و پنچه نرم کند، بینش مورد نیاز جهت درک کد برای توسعه دهنده جدید افزایش پیدا می کند و سرعت پردازش تغییرات و تست کردن آن کاهش پیدا می کند.
در عوض تیم می تواند مراحل زیر را در واحد اتومیک تکاملی ما دنبال کند:
(3) جایگزین کردن اعتبار سنجی قدیمی مبتنی بر password/session با OAuth 2.0
(4) کنار گذاشتن کد اعتبار سنجی قدیمی از برنامه یک-تکه
در این نقطه می توانیم بحث کنیم که تیم ها به معماری هدف نهایی نزدیک تر شده اند.

شکل 9: معماری را به سمت مایکروسرویس ها با گام های اتومیک معماری تکاملی که پس از هر مرحله معماری کلی نسبت به هدف خود بهبود می یابد پیش ببرید، حتی اگر تغییرات کد میانجی آن را از هدف تناسب اندام خود دور کند

واحد اتومیک تجزیه برنامه یک-تکه شامل:
تجزیه سرویس جدید
هدایت تمامی سرویس گیرندگان به سرویس جدید
حذف مسیر های کد قدیمی در برنامه یک-تکه
ضد الگو: سرویس جدید جهت استفاده توسط سرویس گیرندگان جدید را تجزیه و جدا کنید، و هرگز کد قدیمی را کنار نگذارید

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

درباره ی masoud@admin

همچنین ببینید

معماری های Serverless

معماری های Serverless مقدمه: دنیای نرم افزار اکنون در حال پشت سر گذاشتن یکی از …

رویکردهای مختلف جهت Provisioning سرویس های برنامه

رویکردهای مختلفی جهت Provisioning سرویس های برنامه و سرورهایی که این سرویس بر روی اونها …

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

در تلگرام هم همراه شما هستم

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

پیوستن بستن