Mohsen Farokhi - محسن فرخی
Mohsen Farokhi - محسن فرخی
خواندن ۷ دقیقه·۱ سال پیش

مبانی معماری نرم افزار - بخش ششم

در بخش پنجم، heuristicها را مورد بحث قرار دادیم.

در این بخش درباره دو مورد از responseهای Resiliency به نام های Protect و Mitigate صحبت می کنیم. و همچنین موضوع Learnability را نیز بررسی می کنیم.

Responsive vs Preventative

راه حل هایی تحت عنوان Responsive و Preventative وجود دارند که به تفاوت های آن می پردازیم.

راه حل های preventative در طراحی نرم افزار، به راه حل های جلوگیرانه گفته می شوند. یعنی با اتخاذ مکانیزم های دفاعی، جلوی اتفاق افتادن چیزی را بگیریم. برای مثال در دیتابیس فیلد ایمیل را بصورت unique تعریف کنیم. و راه حل های responsive، به دنبال نشان داده یک response مناسب در زمان اتفاق افتادن مشکل هستند. برای مثال وجود یک سرویس مغایرت گیر در سیستم های مالی، یک راه حل responsive است.

از لحاظ Availability، راه حل های responsive دارای availability بالاتری هستند. از این جهت که شما دنبال این نیستید که جلوی یک اتفاق را بگیرید. زمانی که در computation قصد دارید جلوی یک اتفاق را بگیرید، باید در آن مساله جایی برای کنترل متمرکز داشته باشید. وقتی در مورد یک مقدار تکراری صحبت می کنیم، راه حل preventative این است آن را unique index قرار دهیم. و راه حل responsive این است که آن مقدار تکراری ثبت شود و بعد سرویسی مقادیر تکراری را جمع آوری کند و response مناسبی را برگرداند. در مورد unique index، مکانیزم کنترل در درون عملیات وجود دارد و مساله در خود دچار یک گلوگاه ذاتی شده است.

از لحاظ Scalability، راه حل های responsive مقیاس پذیرتر هستند. در برخی از مسائل وقتی از مقیاس خاصی عبور می کنیم، نمی توانیم از راه حل های preventative استفاده کنیم.

از لحاظ Simplicity در سطح technical، راه حل های preventative ساده تر هستند. وقتی که ما جلوی یک اتفاق را می گیریم، از حجم تحلیل هایی که نیاز داریم کاسته می شود. یعنی نیازی به فکر کردن در مورد این موضوع نیست که اگر این اتفاق افتاد، تاثیر آن چگونه خواهد بود و ما چه کاری باید انجام دهیم. اما گاهی اوقات prevent کردن نیز سخت است و یا prevent کردن با performance درست و حفظ availability و scalability سیستم در این شرایط ممکن است پیچیدگی ایجاد کند.

در حوزه Protect کردن، مجموعه ای از راه حل ها را داریم. یکی از responseهایی که در حوزه resiliency می توانیم داشته باشیم، این است که اجازه ندهیم یک failure قابل پیش بینی برای سیستم رخ دهد. یا ریسک اتفاق افتادن را کم کنیم و یا اگر failure اتفاق افتاد، از بخش های دیگر محافظت کنیم.

یکسری از tacticهایی وجود دارد که در مورد رفتار سیستم صحبت می کنند. در Service-Level تغییر رفتاری ممکن است رخ دهد که جلوی یکسری از اتفاقات گرفته شود. برای مثال، ورودی درخواست های سیستم را محدود کنیم که می تواند به اشکال مختلفی اتفاق بیافتد.

تغییر رفتاری که در Service-Level اتفاق می افتد، در راستای حفظ Service-Level Agreement انجام می شود. برای مثال حفظ ترافیک سیستم. این تغییر رفتار، بعضی وقت ها شامل کل scope در application می شود و بعضی وقت ها بر اساس رفتار یک کاربر، IP یا application و غیره اتفاق می افتد. ساده ترین نوع آن، تغییر رفتار برای کل application است. راه حل دیگری که وجود دارد، رفتار را بر اساس system state انجام می دهد. زمانی که system در وضعیتی قرار می گیرد که اصطلاحا Overload می شود، این مکانیزم فعال می شود.

دسته دیگری از راه حل ها وجود دارند که در خانواده protect قرار می گیرند. هدف جلوگیری از بزرگ شدن یک مشکل است. مثل Circuit Breaker یا Timeout که از اتفاق افتادن یک failure بعد از این failure را می گیرند.

در راستای Mitigate کردن، راه حل هایی که وجود دارند در حوزه resiliency تعریف می شوند اما کاملا محدود به resiliency نیستند. برای مثال مجموعه راه حل هایی که در راستای Data Consistency بعد از اتفاق افتادن یک failure انجام می شوند.

موضوع resiliency این است که، زمانی که یک failure اتفاق می افتد یا سیستم به یک failure نزدیک می شود، باید در سیستم ساز و کاری داشته باشیم که سیستم کار خود را ادامه دهد یا حداقل در سطح پایین تری کار خود را ادامه دهد.

بعد از اتفاق افتادن failure و برای recover شدن نرم افزار، راه حل های general وجود دارد.

موضوع Compensation یا Compensation Transaction در حوزه Data Consistency، هر نوع رفتاری است که در راستای برگرداندن وضعیت خراب به وضعیت درست انجام می شود. برای مثال عملیات rollback کردن در کارت به کارت هایی که با موفقیت انجام نمی شود.

راه حل هایی که در حوزه Data Availability انجام می شود. برای مثال داشتن یک replication از داده ها که ممکن است در حوزه دسترسی به گزارش گیری مورد استفاده قرار گیرد.

موضوع resiliency، جزو موضوعاتی است که وضعیت آن باید همیشه بررسی و بهبود داده شود. به این دلیل شاید خیلی از آن ها را از قبل ندانیم. بنابراین مساله Maintaining مطرح می شود. یعنی اینکه کارکرد مساله باید در عمل بررسی شود، مشکلات آن رفع شود و یا بازبینی در آن اتفاق بیافتد. ما از خیلی از failureها اطلاعی نداریم و در داخل عملیات شناسایی می شوند. برای مثال رفتاری خارج از contract که یک third-party ممکن است انجام دهد.

نقش Observability، در گام اول برای این مهم است که خیلی از رفتار های resilient را داشته باشیم. و در گام بعدی برای موضوع ارزیابی، اندازه گیری، تشخیص، برای مثال اینکه چه زمانی حجم درخواست ها بالاست یا چه زمانی تعداد fault و failure بیشتر می شود و یا third-party چه زمانی بیشتر down می شود و غیره که در تحلیل ها مورد استفاده قرار می گیرند.

Learnability

موضوع مهمی دیگری که کمتر به آن توجه می شود، موضوع Learnability است که در quality attributeها در حوزه Cross-Cutting قرار می گیرد.

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

مساله قابلیت یادگیری، عمدتا در زمان و هزینه است و الزاما امکان پذیری آن نیست. زمانی که در مورد دانش صحبت می کنیم، Explicit knowledge را به عنوان یک دانش خیلی سریع و واضح و مشخص می دانیم. موضوع How در کد خیلی وقت ها explicit است. با نگاه کردن به کد متوجه عملکرد آن می شویم. چیزی که در سطح کد explicit نیست، Why است که همیشه Implicit است. بنابراین درک "چرایی" مهم تر "چگونگی" است.

نکته مهم در learnability، تلاش برای تبدیل Implicit knowledge به Explicit knowledge است.

مشخصه learnability بر روی maintainability تاثیر گذار است.

مورد Test یا Specifications، سه quality attribute اصلی Readability, Maintainability Trustworthiness را داریم که اگر وجود نداشته باشند تست با مشکلات جدی روبرو خواهد شد.

در راستای learnability در سطح Code، در جهت خوانایی کد مشخصه Readability را داریم. مساله Comment در جایی که به تشریح کد می پردازد، نشان از عدم خوانایی کد دارد. اما اگر commentها به مساله چرایی مساله بپردازند می توانند مفید باشند. در جایی که امکان readable کردن کد به هر دلیلی وجود ندارد، می توانیم از comment استفاده کنیم و آن را تشریح کنیم.

در راستای learnability در مورد Simple Design یا طراحی ساده، موضوعی سادگی با موضوع آسان بودن نباید اشتباه گرفته شود. برای یک سوال پیچیده نمی توانیم یک جواب آسان دهیم. منظور از سادگی، الزما تعداد کم اِلمان ها نیست. منظور این است که چیز اضافه ای وجود نداشته باشد و آن چیزهایی باید وجود داشته باشند که مساله به آنها نیاز دارد.

موضوع Integrity جزء موضوعات مهم در learnability است که به یکپارچگی یا وحدت رویه می پردازد. منظور استفاده همه از یک معماری یا روش خاصی نیست. منظور زمانی است که وقتی با مسائل مشابه ای روبرو هستیم، برای آنها از روش های مختلفی استفاده نکنیم و جایی که در مورد مفاهیم یکسان صحبت می کنیم، زبان و فضا تغییر نکند. برای مثال، به مساله naming در کد می توانیم اشاره کنیم.

در راستای learnability موضوع Source Control فارغ از نگاه ابزاری جهت نگهداری کد و تغییرات آن، یک منبع خیلی غنی از دانش و اطلاعات می باشد. تحلیل هایی روی آن می توان انجام داد که اطلاعات ارزشمندی را به ما می دهد و در حوزه learnability اهمیت بالایی دارد. نقطه شروع مطالعه برای اعمال تغییرات و آنالیز مساله می تواند مطالعه source control باشد.

معماری نرم افزارsoftware architectureLearnabilityمحسن فرخی
شاید از این پست‌ها خوشتان بیاید