چطور در محیط عملیاتی زنده بمانیم؟ چند دقیقه با کتاب Release it

خیلی از ما توسعه‌دهندگان نرم‌افزار، درد یک فرایند استقرار طولانی و دلهره‌آور را چشیده‌ایم. ممکن است پس از به پایان رسیدن این فرایند سخت، با تجربه‌ی ناخوشایند بیدار شدن از خواب با تماس‌های تلفنی مواجه شده باشیم. حتی شاید به دلیل پایین آمدن سرویس، از دست رفتن اطلاعات و یا نشت آن تا مرز از دست رفتن شغلمان پیش رفته باشیم. مایکل نایگارد در کتاب Release It تلاش می‌کند راه‌کارهایی به ما ارائه کند تا کمتر با چنین مشکلاتی برخورد کنیم. او یک مهندس نرم‌افزار است که سال‌ها در زمینه‌‌ی توسعه و استقرار سیستم­‌های نرم‌افزاری تجربه دارد. او در این کتاب چکیده‌ای از تجربیات خود را به صورت ترکیبی از داستان و درس تدوین کرده است.برای بسیاری از ما توسعه‌دهندگان، تعریف پایان کار، اضافه شدن کد به مخزن است؛ چه اضافه شدن یک ویژگی باشد و چه رفع یک خطا. توسعه‌دهندگانِ باتجربه‌تر به این بسنده نمی‌کنند. آن‌ها تا زمانی که تست نکنند، کار خود را تمام شده نمی‌دانند. عده‌ای هوشمندانه قبل از اضافه کردن کد به مخزن با اضافه کردن تست‌های خودکار، زحمت کار خود را کاهش می‌دهند. اما در نهایت، توسعه‌دهندگان اغلب پس از پاس شدن تست‌ها، کار خود را تمام شده می‌دانند. نایگارد این مسأله را به زیبایی مطرح می‌کند:شما سخت روی پروژه کار کرده‌اید. به نظر می‌­رسد همه‌­ی ویژگی‌­ها (feature) کامل شده‌­اند و حتی اکثر آن‌­ها تست هم دارند. می‌توانید نفسی راحت بکشید. کار شما تمام است.درست است؟آیا «تکمیل ویژگی­‌ها» به معنی «آمادگی برای محیط عملیاتی» است؟ آیا سیستم شما واقعاً برای استقرار آماده است؟ آیا می‌­تواند بدون شما توسط تیم عملیات اجرا شده و با هجمه­‌ی کاربران واقعی روبرو شود؟ آیا در این فکر غرق شده‌اید که دیروقت با تماس ­های اضطراری و هشدار مواجه خواهید شد؟ به نظر می‌­رسد توسعه‌ی نرم‌­افزار چیزی بیش از اضافه کردن ویژگی­‌ها باشد.در حقیقت، کار توسعه‌دهنده با پاس شدن تست‌ها تمام نمی‌شود، بلکه تازه باید برای محیط عملیاتی آماده شد. Release It شامل موضوعاتی است که توسعه‌دهنده باید برای زنده ماندن در محیط عملیاتی مد نظر داشته باشد.کتاب از چهاربخش تشکیل شده و شیوه­‌ی نگارش آن بسیار جالب است. هر بخش با یک داستان شروع می‌­شود؛ داستانی از حوادث در محیط عملیاتی؛ حوادثی که منجر به وارد شدن صدمه به دارایی‌های مالی یا معنوی ذی‌نفعان می‌شود. داستان‌ها واقعی بوده و بدون واسطه، توسط نویسنده تجربه شده‌اند؛ اما نام‌ها و جزییات تغییر داده شده تا محرمانگی حفظ شود.بخش اول «ایجاد پایداری» نام دارد. نایگارد با «اکسپشنی که یک خط هوایی را زمین زد» شروع می‌کند؛ داستان به‌­روزرسانی بخشی از یک سیستم، طی یک فرایند از قبل طراحی شده و بر اساس برنامه. در نهایت این به‌­روزرسانی منجر به بروز اختلال در سایر سیستم­‌ها از جمله سیستم صدور بلیط می‌­شود. تا زمانی که مسئله برطرف شود، هزینه­ زیادی هم از لحاظ مالی و هم از لحاظ آبروی کسب و کار، به خط هوایی وارد شده است.یکی از کارهایی که مایکل نایگارد در این کتاب انجام داده است، جمع­ آوری و نام­‌گذاری چیزهایی است که احتمالاً ما هم هنگام توسعه یا استقرار با آن برخورد کرده‌ایم. شاید هم به طور پراکنده در مورد آن مطالعه کرده باشیم؛ کاری مثل آن‌چه که کتاب الگوهای طراحی انجام داد. نایگارد ضد الگوهای پایداری را به ما معرفی می‌­کند. ضد الگوها عادت‌هایی هستند که نه تنها به پایداری سیستم کمکی نکرده، بلکه باعث تضعیف آن نیز می‌شوند.در بخش اول 12 ضد الگوی پایداری معرفی می‌شود. بعضی از این الگوها با هم ارتباط یا هم‌پوشانی داشته و یا یکدیگر را تقویت می‌کنند. بعد از مطرح کردن ضد الگوهای پایداری، نوبت به معرفی الگوهای پایداری می‌رسد. در این‌جا هم 12 الگو معرفی می‌شود که کم و بیش در تناظر با ضد الگوهای یاد شده هستند. یکی از الگوهای جالب Let It Crash است:گاهی اوقات بهترین کاری که می شود برای پایدارسازی در سطح سیستم انجام داد، رها کردن پایداری در سطح مؤلفه است. در دنیای Erlang به این روش، فلسفه «let it crash» گفته می شود. ... می دانیم که نمی توان به جلوگیری از همه خطاهای ممکن امیدوار بود. ابعاد، گسترش یافته و فضای حالت به صورت نمایی رشد می‌کند. راهی برای تست همه چیز و پیش بینی همه‌ی راه‌های شکست سیستم وجود ندارد. باید فرض کنیم که خطا رخ خواهد داد.سوال کلیدی این است، «با خطا چه کنیم؟». اغلب تلاش می کنیم شرایط را بازیابی کنیم. یعنی سیستم را با استفاده از exception handler ها و ... به یک حالت شناخته‌شده‌ی خوب برگردانیم. آیا این کافی است؟پاک‌ترین حالتی که برنامه‌ی شما می تواند داشته باشد، حالتی که درست بعد از شروع به کار دارد. رویکرد «let it crash» می‌گوید جبران خطا سخت و غیرقابل اتکاست، بنابراین هدف ما باید رسیدن هرچه سریع‌تر به آن وضعیت پاک باشد.در واقع نایگارد در این‌جا از ما دعوت می‌کند برای داشتن سیستم‌های پایدار، در شرایط خطا مولفه‌ها را هر چه سریع‌تر پایین بیاوریم!موضوع بخش بعدی کتاب «طراحی برای محیط عملیاتی» است. بارها شنیده‌ایم و دیده‌ایم که چیزی در محیط توسعه کار می‌کند اما در محیط عملیاتی با خطا مواجه می‌شود؛ جدال قدیمی میان تیم توسعه و استقرار. چیزی که نایگارد در این‌جا توجه ما را به آن جلب می‌کند تفاوت‌های محیط توسعه و محیط عملیاتی است. این تفاوت‌ها موجب بروز نگرانی‌هایی در محیط عملیاتی می‌شود. علاوه بر این، نکته‌ی دیگری که او به زیبایی به آن اشاره می‌کند در نظر داشتن افراد تیم عملیات است:طراحی برای محیط عملیاتی یعنی فکر کردن به مشکلات عملیاتی به عنوان نگرانی‌های دست اول. این مشکلات شامل شبکه محیط عملیاتی است که ممکن است بسیار متفاوت از محیط توسعه باشد. همچنین شامل لاگ زدن و نظارت (monitoring)، کنترل runtime، و امنیت می شود. طراحی برای محیط عملیاتی همچنین به معنی طراحی برای افرادی است که کار عملیات را انجام می‌دهند، چه تیم جداگانه‌ای باشند و چه در توسعه ادغام شده باشند.سپس نایگارد لایه‌های نگرانی را مطرح می‌کند. در هر لایه الفبا معرفی شده و قدم‌های بعدی برای مطالعه‌ی توضیح داده می‌شود.پس از «طراحی برای محیط عملیاتی» نوبت به «تحویل سیستم» می‌رسد. داستان این بخش «در انتظار گودو» نام دارد. در این داستان نایگارد دوتجربه‌ی متفاوت از استقرار در محیط عملیاتی را تعریف می‌کند. یکی با تلاش بیش از 40 نفر متخصص در یک بازه‌ی 24 ساعته و دومی با فشرده شدن یک دکمه توسط یک سرمایه‌گذار که در حال بازدید از شرکت بود!نایگارد از خودکارسازی استقرار، خط لوله‌ی build و استقرار مستمر (Continuous Deployment) صحبت می‌کند. او مفاهیم اصلی را به طور خلاصه مطرح کرده و برخی از ابزارهای موجود را نیز معرفی می‌کند. من به جزییات این موارد نمی‌پردازم و صرفاً به چند نکته‌ی جالب بسنده می‌کنم.یکی از نکات جالب pets vs. cattle است. در گذشته تعداد ماشین‌هایی که با آن سروکار داشتیم محدود بود. هر ماشین نقش مشخص و شناخته شده‌ای داشت. حتی گاهی تک‌تک ماشین‌ها را با اسمشان صدا می‌کردیم؛ مثل حیوانات خانگی. اما با گذر زمان تعداد ماشین‌ها بیشتر شد. نحوه‌ی کار با آن‌ها هم تغییر کرد. امروز ما با گله‌ای از ماشین‌ها مواجه‌ایم. این مسئله چطور روی کار ما تأثیر خواهد گذاشت؟ دیگر نام ماشین‌ها را نمی‌دانیم. دیگر نمی‌دانیم چه چیزی روی چه ماشینی اجرا می‌شود. دیگر از بین رفتن یک ماشین خاص برایمان اهمیت ندارد.نکته‌ی دیگری که در این فضای جدید اهمیت پیدا می‌کند رسیدگی به نسخه‌هاست. در شرایط پیچیده‌تر امروز باید بتوانیم نسخه‌های متفاوت سرویس‌ها را با یکدیگر هماهنگ نگه‌داریم. مصرف کننده‌ی یک سرویس، تیم یا محصول دیگری است. چطور نسخه‌های جدید را بدون نگرانی انتشار دهیم؟ اینجا صحبت از backward compatibility، نوشتن تست‌ها توسط مشتری و سخت‌گیری و بدبینی در تعامل با سایر سرویس‌ها است.در بخش آخر نایگارد، از «حل مشکلات سیستمی» صحبت می‌کند. در فصل اول این بخش، او از ضرورت تطبیق‌پذیری (Adaptability) صحبت می‌کند. در شرایط کنونی، مقاومت در برابر تغییر دیگر یک گزینه نیست. اکنون صحبت از کوتاه کردن چرخه‌ی بازخورد و رفع موانع است؛ این‌که چطور خود را برای استقبال از در آغوش گرفتن تغییرات آماده کنیم.در فصل بعدی نایگارد وارد موضوع مهندسی آشوب (Chaos Engineering) می‌شود. مهندسی آشوب یک موضوع نوظهور در عرصه‌ی نرم‌افزار است و طی چند سال گذشته تحولات زیادی داشته است. مهندسی آشوب تلاش می‌کند نرم‌افزار را در مقابل فجایعی که ممکن است در محیط عملیاتی رخ دهند، مقاوم کند. نایگارد این‌طور آن را معرفی می‌کند:گفتگویی را تصور کنید که این‌طور شروع می‌شود:شما می‌گویید: «سلام رئیس، من می‌خوام تو محیط عملیاتی یه تعدادی از ماشینا رو بترکونم. یه کم از اینور و یه کم از اون‌ور. نباید مشکلی پیش بیاد.»فکر می‌کنید ادامه‌ی گفتگو چطور پیش‌ خواهد رفت؟ ممکن است با مراجعه‌ی یک نفر از منابع انسانی و دستور تمیز کردن میز کارتان تمام شود. شاید هم یک قرار ملاقات با نزیک‌ترین مطب روانشناسی! پایین آوردن ماشین‌ها ممکن است یک ایده‌ی افراطی باشد، اما جنون نیست. این یک تکنیک از یک مکتب نوظهور است به نام «مهندسی آشوب».این مقدمه شاید مضحک به نظر برسد؛ اما ایده‌ی اصلی مهندسی آشوب همین است: خراب‌کاری نیمه‌کنترل شده در محیط عملیاتی! در ادامه توضیح بیشتری در مورد تاریخچه‌ی این مکتب و نگاه آن به نحوه‌ی مقاوم‌سازی سیستم‌ها داده می‌شود.آن‌چه که خواندید گوشه‌ای از مطالبی است که در کتاب Release It آمده است. خواندن کتاب و مرور دوباره‌ی آن برای نوشتن این مطلب، برای من لذت‌بخش و آموزنده بود. امیدوارم توانسته باشم این حس را در خوانندگان هم ایجاد کرده باشم.