حالت تاریک
فصل ۳ — ماژولاریتۀ معماری
خلاصهٔ تحلیلی — این متن خلاصهای تحلیلی و مستقل به فارسی است، نه ترجمهٔ واژهبهواژه.
مسئله و زمینه
ماژولارکردن سیستم صرفاً پروژهای برای «مدرنشدن» نیست. یک مونولیت زمانی نامزد جداسازی است که مسئلههای کسبوکار به ویژگیهای معماری قابل مشاهده وصل شوند: تغییر کند و پرریسک، آزمونهای حجیم و ناقص، انتشارهای نادر، ناتوانی در پاسخ به رشد، یا خرابی یک قابلیت که کل محصول را از دسترس خارج میکند.
در داستان Sysops Squad، همین پیوند است که درخواست بازنویسی را از سلیقهٔ فنی به پروندهٔ کسبوکاری تبدیل میکند: گزارشگیری و survey باعث اختلال در جریان حیاتی ثبت تیکت شدهاند، تغییر کوچک کل سامانه را درگیر میکند و رشد بار، توقف ایجاد میکند.
مفاهیم و الگوهای مرکزی
محرکهای ماژولاریتۀ معماری
هدف تجاری معمولاً سرعت ورود به بازار و مزیت رقابتی است. این هدفها از مجموعهای از ویژگیهای فنی پدید میآیند:
- نگهداشتپذیری: آسانی افزودن، تغییر و حذف قابلیت یا بهروزرسانی داخلی. coupling ورودی، cohesion، پیچیدگی، اندازه و مرزبندی دامنه بر آن اثر دارند.
- آزمونپذیری: هم سهولت آزمون و هم پوشش مناسب آن. واحد تغییر کوچکتر، مجموعهآزمون هدفمندتر و تشخیص خطای مرتبطتر میسازد.
- قابلیت استقرار: سهولت، بسامد و ریسک انتشار. انتشارهای بزرگ و کمتعداد، تغییرهای نامرتبط را در یک ریسک واحد جمع میکنند.
- مقیاسپذیری و کشسانی: اولی پاسخگویی در رشد تدریجی بار است؛ دومی پاسخ سریع به جهش ناگهانی بار. کشسانی به کوچکبودن واحد استقرار و زمان شروع پایینتر وابستگی بیشتری دارد.
- دسترسپذیری/تحمل خطا: خرابی یک واحد نباید سرویسهای نامرتبط را زمینگیر کند.
سطح تغییر و مرز دامنه
در مونولیت لایهای، یک قابلیت مانند تغییر در wishlist ممکن است UI، منطق و database را با هم درگیر کند؛ سطح تغییر، سطح کل برنامه است. در معماری سرویسمحور، تغییر میتواند در سطح دامنه محدود شود و در microservicesِ مناسب، به سطح یک قابلیت برسد. این کاهش دامنهٔ تغییر فقط با اتصال کمهزینهٔ میان واحدها اتفاق میافتد، نه صرفاً با افزایش تعداد deployableها.
ماژولاریتۀ معماری مساوی توزیع نیست
مونولیت ماژولار یا microkernel هم میتوانند با جداسازی دامنه و pluginهای خوب، نگهداشتپذیری و آزمونپذیری بهتری بدهند. توزیع، latency، خطاهای شبکه و پیچیدگی عملیات میآورد؛ بنابراین باید وقتی انتخاب شود که نیاز به استقلال استقرار، مقیاس یا جداسازی خطا، آن هزینه را توجیه کند.
مصالحهها
ریزترشدن سرویسها بهطور خودکار کیفیتها را بهتر نمیکند. با افزایش ارتباط بین سرویسها:
- محدودهٔ آزمون دوباره بزرگ میشود، چون تغییر یک سرویس به قرارداد و رفتار دیگران وابسته است.
- انتشار مستقل به انتشار هماهنگ یا ترتیبی تبدیل میشود؛ نشانهٔ «big ball of distributed mud».
- فراخوانی همگام، زنجیرهٔ ظرفیت و خرابی میسازد؛ سرویس سریع منتظر سرویس کند میماند.
مقیاسپذیریِ انتخابی مزیت اصلی تفکیک است، اما اگر یک تراکنش برای تکمیل به تماسهای همگام فراوان نیاز دارد، گلوگاه کندتر سقف کل workflow میشود. تحمل خطا نیز وقتی واقعی است که dependencyهای همگام، شکست را منتشر نکنند.
راهنمای عملی
- از شکایتهای واقعی کسبوکار شروع کنید و برای هرکدام ویژگی معماری و معیار متناظر تعیین کنید.
- baseline بگیرید: زمان تغییر تا production، زمان اجرای آزمون، بسامد انتشار، نرخ خرابی، بار و اثر خرابی هر قابلیت.
- ابتدا مرزهای دامنه و نقاط تماس را بهبود دهید؛ استقرار جداگانه را نتیجهٔ مرز خوب بدانید، نه هدف مستقل.
- برای مسیرهای حیاتی، dependencyهای همگام را کم و رفتار در قطع سرویس را طراحی کنید.
- در ADR، منفعت مورد انتظار و هزینههای مهاجرت—تأخیر featureها، هزینهٔ تیم و نیاز به تغییر pipeline و داده—را همزمان ثبت کنید.
نکات کلیدی فصل
- ماژولاریتۀ معماری باید پاسخ مسئلهٔ کسبوکار باشد، نه واکنش خودکار به بزرگشدن کد.
- چابکی از نگهداشتپذیری، آزمونپذیری و deployability ساخته میشود.
- تفاوت scalability و elasticity در افق زمانی و سرعت واکنش است.
- افزایش تعداد سرویسها بدون کاهش coupling، مونولیت را فقط در شبکه پخش میکند.
یادداشت مترجم
- «ماژولاریتۀ معماری» برای architectural modularity بهکار رفته تا با صرف ماژولبندی کد اشتباه نشود.
- «کشسانی» برای elasticity و «مقیاسپذیری» برای scalability بهکار رفتهاند؛ فصل آنها را دو نیاز نزدیک اما متفاوت میداند.