در ادامه مرور بخشهایی از کتاب Microservices Patterns: With Examples in Java نوشته Chris Richardson به مزایا و معایب معماری یکپارچه رسیدیم.
اگر میخواهید با من در این ماجرای هیجانانگیز و تجربه ماری در شرکت FTGO همراه شوید لطفا ابتدا به پست قبلی سر بزنید:
معماری میکروسرویس - فرار از جهنم یکپارچه!
و اما حالا لطفا بیاید تا ادامه داستان را با هم باشیم:
در روزهای اولی که تازه FTGO شروع به کار کرده بود، یک نرمافزار کوچک بود و استفاده از معماری یکپارچه مزایایی برای آن به همراه داشت:
امکان ایجاد تغیرهای افراطی به آسانی- کد و اسکیمای دیتابیس را میتوانستند به راحتی عوض کرده و بیلد و دیپلوی کنند.
اما به مرور زمان، توسعه، تست، دیپلوی و مقیاسپذیری دشوارتر شد. اما حالا ببینیم چرا؟
متاسفانه در طول زمان توسعهدهندگان FTGO دریافتند که معماری یکپارچه محدودیتهای زیادی دارد. اپلیکیشنهای موفقی مانند FTGO به مرور زمان بزرگتر از آن میشوند که در معماری یکپارچه بگنجند! در هر اسپرینت تیم توسعهی FTGO تعدادی استوری را پیادهسازی میکردند که این سبب بزرگتر شدن کد و پایگاهداده میشد. از طرفی هرچقدر که شرکت موفقتر میشد، تیم توسعه را بزرگتر میکرد. این بزرگ شدن تیم، سربارهای مدیریتی زیادی ایجاد میکرد و البته طبیعتا با همین نسبت، کار توسعه جلو نمیرفت.
آن تیم توسعه کوچکِ روزهای اول، اکنون به چندین تیم اسکرام تبدیل شده بود که هر کدام بخشی از کارکرد را پیادهسازی میکردند. اما در نهایت یک فایل اجرایی وجود داشت. چنین روندی، توسعه را سخت کرد و عملا توسعه به سبک اجایل یا چابک را غیرممکن ساخت. اما چنین اتفاقی چگونه رخ داد؟ بیایید دقیقتر نگاه کنیم.
به مرور زمان کد به قدری بزرگ و پیچیده میشود که امکان اینکه یک برنامهنویس همه آن را بفهمد، ممکن نیست. در نتیجه این امر دیباگ و افزودن یک فیچر جدید فرایندی زمانبر و دشوار و خسته کننده است. در چنین شرایطی ددلاینها مرتبا از دست میروند. برنامهنویسی که نداند این کد دقیقا چطور کار میکند، چگونه میتواند فیچر جدید را به درستی به آن اضافه کند؟ همچنین با هر تغییر جدید کد پیچیدهتر و دشوارتر میشود و این چرخه باطل ادامه دارد! حتی ماژولاریتی که در قسمت قبل توضیح دادیم، نمیتواند در واقعیت این مشکل را کامل حل کند. در نهایت ماری که CTOشرکت FTGO بود فهمید که تنها یک راهکار برای نرمافزار بزرگ و پیچیده وجود دارد: معماری میکروسرویس.
بزرگ شدن یک اپلیکیشن روند توسعه را کند میکند. گاها در حدی این بزرگ شدن رخ میدهد که در IDE برنامهنویس به راحتی نمیگنجد. بنابراین زمان زیادی برای شروع برنامه صرف میشود و برنامهنویس نمیتواند مرتبا با چرخه edit-build-run-test جلو برود.
یکی دیگر از مشکلاتی که FTGO با آن دست و پنجه نرم میکرد، دشوار بودن فرایند دیپلوی است. گاها روزها باید طول میکشید تا بتوانند یک فیچر که کامیت شده را به پروداکشن برسانند. اگرچه که ساختار تیمها اجایل بود و اسپرینتهای دو هفتهای وجود داشت، اما از زمانی که یک کد به درستی کامپایل میشود تا زمانی که این کد در پروداکشن دیپلوی شود، زمانی طولانی در حد چندین روز بود این در حالیست که برای مثال در سال 2011 آمازون هر تغییر را به طور میانگین در 11.6 ثانیه به پروداکشن منتقل میکرد! یکی بودن فایل اجرایی و طولانی شدن پروسه تست از اصلیترین دلایل دشوار بودن فرایند دیپلوی در FTGOبود.
به مرور زمان مقیاسپذیری نیز دشوار شد. با بزرگ شدن کد، ماژولهای مختلف از نظر منابعی که نیاز دارند، نیازمندیهای متفاوتی دارند که گاها متناقض با یکدیگر است. برای مثال داده رستورانها نیاز است روی یک دیتابیس بزرگ in-memoryباشد بنابراین نیاز به سروری که مموری زیاد دارد. در مقابل ماژول پردازش تصویر نیاز به سروری دارد که CPUخوبی داشته باشد. این ماژولها همگی در یک اپلیکیشن هستند، پس سروری که بخواهد این اپلیکیشن روی آن اجرا شود، کانفیگهای متعدد و خاصی نیاز است داشته باشد.
یکی از نکات مهم در قابلیت اطمینان، امکان تست است. اما در FTGO تست بسیار زمانبر و دشوار شده است. بنابراین وقتی قابلیت تست به آسانی وجود نداشته باشد، قابلیت اطمینان را تحت تاثیر قرار میدهد. از طرفی تمام ماژولها همزمان با هم کار میکنند بنابراین قابلیت fault isolation عملا وجود ندارد. برای مثال اگر بخشی از برنامه به دلیل memort leak کرش کند، همه اجزا به دلیل آن که بهم وابستهاند کرش خواهند کرد در چنین حالتی دیباگ کاری دشوار و گاها غیرممکن است. چنین شرایطی اعتماد مشتری به سیستم را پایین میآورد و اهداف کسب و کار را به خطر میاندازد.
با گذشت زمان، یک سیستم که معماری یکپارچه دارد، بزرگ و بزرگتر میشود، دنیای تکنولوژی به سرعت عوض میشود اما در این سیستم از فریمورکهای قدیمی استفاده شده که به راحتی نمیتوان آنها را جایگزین کرد. معماری یکپارچه به راحتی اجازه نمیدهد که بتوان فریمورک یا زبان جدید در پروژه اضافه کرد. بنابراین از سویی نگهداری پروژه به مرور زمان دشوارتر میشود و امکان استفاده از ویژگیهای جدید میسر نیست و از سوی دیگر انتخاب تکنولوژی تنها در ابتدای پروژه ممکن خواهد بود و بعدا به سختی میتوان آن را تغییر داد. برای مثال در FTGO به دلیل مشکلاتی، نسخه فریمورک بروزرسانی نشده بود و در نتیجه با نسخههای جدید Springهمخوانی نداشت. همچنین برنامهنویسان FTGO مایل بودند بخشهایی را با زبانهای non-JVMمانند GoLang یا NodeJS بنویسند که متاسفانه چنین چیزی در معماری یکپارچه ممکن نیست.
اگر دوست دارید، در پستهای بعدی ادامه داستان را دنبال کنین تا ببینیم این معماری یکپارچه چگونه به معماری میکروسرویس تبدیل میشود و چرا میکروسرویس برای این سیستم انتخاب خوبی است؟
منبع:
Microservices Patterns: With Examples in Java Book by Chris Richardson
پست بعدی: