پرش به محتویات

ساختن زیرساختی آرام

سیستم‌های پایدار باید بار ذهنی را کم کنند، نه اینکه آن را از دوش ماشین‌ها روی دوش آدم‌ها بگذارند. زیرساخت آرام وضعیتش را شفاف نشان می‌دهد، راه‌های غافلگیرکننده بودن یک تغییر را محدود می‌کند و همیشه مسیر روشنی برای بازیابی باقی می‌گذارد.

رابط‌های ساده و ملال‌آور را ترجیح دهید

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

service.yml
service:
  healthcheck: /healthz
  timeout: 5s
  retries: 3

جزئیات از قراردادی که سیستم ارائه می‌دهد کم‌اهمیت‌ترند. اپراتور باید بتواند سریع به سه پرسش پاسخ دهد: سرویس آماده است؟ به چه چیزهایی وابسته است؟ و اگر یکی از وابستگی‌ها از دسترس خارج شود چه اتفاقی می‌افتد؟ اگر پاسخ‌دادن به این پرسش‌ها نیازمند خواندن پیاده‌سازی باشد، رابط عملیاتی هنوز کامل نیست.

ساده‌بودن یعنی هماهنگی هم. سرویس‌های مشابه باید برای بررسی سلامت، لاگ، متریک، مهلت زمانی و رفتار خاموش‌شدن نام‌های یکسانی داشته باشند. این هماهنگی تجربهٔ کار با یک سیستم را به شهودی مفید برای سیستم بعدی تبدیل می‌کند.

هشدارها را برای تصمیم‌گیری طراحی کنید

هشدار باید از یک انسان بخواهد تصمیمی بگیرد. اگر کسی لازم نیست کاری انجام دهد، آن رویداد به لاگ، متریک یا داشبورد تعلق دارد؛ نه کانال پیجینگ.

هشدار خوب نشانه‌ای را که کاربر می‌بیند شرح می‌دهد و اطلاعات کافی برای شروع بررسی فراهم می‌کند:

  • چه چیزی و برای چه کسانی خراب شده است؛
  • خرابی از چه زمانی شروع شده؛
  • کدام تغییر اخیر ممکن است به آن مربوط باشد؛
  • لاگ‌ها و متریک‌های مرتبط کجا هستند؛
  • چه اقدام‌های امنی در دسترس‌اند.

مصرف CPU به‌تنهایی به‌ندرت هشدار مفیدی است. افزایش مداوم زمان پاسخ همراه با پرشدن ظرفیت workerها به نشانه‌ای عملی بسیار نزدیک‌تر است. هدف دیدن تک‌تک حرکت‌های داخلی نیست؛ باید بفهمیم سیستم چه زمانی دیگر نمی‌تواند به وعده‌هایش عمل کند.

کیفیت هشدار به نگه‌داری نیاز دارد. پس از رخدادها هشدارهای پرسر‌وصدا را مرور کنید، مواردی را که هیچ‌وقت به اقدامی منجر نمی‌شوند حذف کنید و مسیر ارسالشان را بیازمایید. هشدار بی‌نقصی که به کانالی متروک می‌رود همچنان یک هشدار شکست‌خورده است.

برای خرابی مرز بگذارید

سیستم آرام درون مرزهای مشخص خراب می‌شود. مهلت زمانی صریح تعیین کنید تا کاری برای همیشه منتظر نماند، تعداد تلاش‌های دوباره را محدود کنید تا وابستگی گرفتار زیر بار بیشتر نرود و سقف منابع بگذارید تا یک workload تمام میزبان را مصرف نکند.

تلاش دوباره به توجه ویژه نیاز دارد. تلاش‌های فوری هنگام قطعی می‌توانند بار را چند برابر و بازیابی را دشوارتر کنند. تعداد محدودی تلاش با وقفهٔ نمایی و jitter انجام دهید؛ سپس خطایی روشن برگردانید یا کار را به صف بسپارید. هر سیاست retry باید نقطهٔ پایان داشته باشد.

همین اصل دربارهٔ وابستگی‌ها هم صادق است. سرویس باید بداند کدام وابستگی برای شروع ضروری است، کدام می‌تواند موقتاً قطع باشد و حالت تنزل‌یافته چگونه گزارش می‌شود. وقتی شکست جزئی پیش از استقرار در نظر گرفته شود، مدیریت آن آسان‌تر است.

تغییرها را کوچک و برگشت‌پذیر نگه دارید

تغییر بزرگ فضای جست‌وجوی بزرگی ایجاد می‌کند. وقتی پس از استقرار رخدادی پیش می‌آید، تیم باید بفهمد کدام بخش تغییر بر سیستم اثر گذاشته است. تغییرهای کوچک و پیوسته پاسخ‌دادن به این پرسش را آسان‌تر می‌کنند.

یک فرایند تغییر آرام معمولاً این ویژگی‌ها را دارد:

  1. نتیجهٔ مورد انتظار و روش اعتبارسنجی نوشته شده است.
  2. پیکربندی بازبینی و در کنترل نسخه نگه‌داری می‌شود.
  3. استقرار مرحله‌ای است و یک‌باره همه‌جا انجام نمی‌شود.
  4. پس از هر مرحله سلامت سیستم بررسی می‌شود.
  5. مسیر بازگشت یا حرکت رو به جلو پیش از شروع تغییر معلوم است.

خودکارسازی باید این گام‌ها را تکرارپذیر کند، اما نباید آن‌ها را پنهان کند. pipeline استقرار وقتی امن‌تر است که اپراتور ببیند چه چیزی در حال تغییر است و بتواند میان مرحله‌ها آن را متوقف کند.

بازیابی را بخشی از طراحی بدانید

نسخهٔ پشتیبان تا وقتی بازیابی آن تمرین نشده فقط یک فرضیه است. rollback، مانور بازیابی و مستندسازی حالت‌های خرابی را مثل قابلیت‌های محصول جدی بگیرید.

یک پیش‌فرض مفید

مسیر رایج بازیابی را خودکار کنید و مسیر دستی را هم کنار آن مستند نگه دارید.

یک مانور خوب با پرسشی مشخص شروع می‌شود: آیا می‌توان این سرویس را روی میزبانی خالی، فقط با نسخهٔ پشتیبان، مخزن پیکربندی و runbook بازسازی کرد؟ آزمایش در محیطی جدا، اعتبارنامه‌های گم‌شده، وابستگی‌های مستندنشده، نسخه‌های ناسازگار و مراحلی را آشکار می‌کند که فقط در حافظهٔ یک نفر وجود دارند.

هدف‌های بازیابی باید دقیق باشند. RPO می‌گوید چه مقدار از دست‌رفتن داده پذیرفتنی است و RTO مشخص می‌کند بازیابی چقدر می‌تواند طول بکشد. این دو حد، تناوب و مدت نگه‌داری پشتیبان‌ها، replication و میزان خودکارسازی لازم را تعیین می‌کنند.

راهنمای عملیاتی را نزدیک به واقعیت نگه دارید

runbook باید آن‌قدر کوتاه باشد که زیر فشار هم به کار بیاید. با بررسی‌هایی شروع کنید که حالت‌های رایج خرابی را از هم جدا می‌کنند؛ سپس راهکارهای امن و شرایط ارجاع مسئله را بنویسید. کنار هر دستور نتیجهٔ موفق را توضیح دهید و دربارهٔ اثرات مخرب هشدار بدهید.

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

آرامش، یک نتیجهٔ مهندسی است

زیرساخت آرام زیرساختی نیست که هرگز خراب نشود. زیرساختی است که هنگام خرابی شفاف حرف می‌زند، آسیب را مهار می‌کند و مسیری تمرین‌شده برای بازگشت به وضعیت سالم در اختیار آدم‌ها می‌گذارد.

بیشتر این کارها پرزرق‌وبرق نیستند: رابط‌های یکدست، هشدارهای مفید، retry محدود، تغییرهای کوچک، پشتیبان‌های آزموده و runbookهای به‌روز. این انتخاب‌ها کنار هم بداهه‌کاری را با شواهد جایگزین می‌کنند؛ چیزی که به اپراتور اجازه می‌دهد حتی ساعت ۳ بامداد هم سنجیده واکنش نشان دهد.