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

مشکل این نیست که سرویس‌ها به اینترنت وصل‌اند. مشکل این است که ساختن، به‌روزرسانی و راه‌اندازی دوباره‌ی آن‌ها به اینترنت وصل است، و این وابستگی‌ها تا روزی که لازمشان داشته باشید دیده نمی‌شوند.

وابستگی‌هایی که معمولاً دیده نمی‌شوند

  • مخزن بسته‌ها — apt، npm، pip و go به‌طور پیش‌فرض از سرورهای خارج از کشور دانلود می‌کنند. هر build و هر نصب تازه به آن‌ها نیاز دارد.
  • ایمیج کانتینر — Docker Hub درخواست‌هایی را که از نشانی‌های ایرانی می‌آید رد می‌کند، حتی در روزهای عادی. خط لوله‌ای که با FROM node:22 شروع می‌شود، در عمل به یک سرور خارجی وابسته است.
  • زمان — سرورها ساعتشان را از سرورهایی مثل ntp.ubuntu.com یا time.windows.com می‌گیرند. بدون همگام‌سازی، ساعت هر دستگاه روزی چند ثانیه جابه‌جا می‌شود؛ بعد از چند هفته، کدهای ورود دومرحله‌ای، اعتبار گواهی‌ها و ترتیب لاگ‌ها به هم می‌ریزد.
  • DNS — سرورهایی که مستقیم از 8.8.8.8 یا 1.1.1.1 استفاده می‌کنند، ممکن است در قطعی حتی نام سرویس‌های داخلی را هم پیدا نکنند.
  • فعال‌سازی لایسنس — بعضی نرم‌افزارهای تجاری در هر راه‌اندازی یا هر چند روز یک بار با سرور سازنده تماس می‌گیرند.
  • هشدار — اگر هشدارهای مانیتورینگ فقط از راه سرویسی خارجی ارسال شود، درست روزی که بیشترین نیاز را دارید هیچ هشداری نمی‌رسد.
  • منابع وب‌سایت — فونت، اسکریپت یا کپچایی که از CDN خارجی بارگذاری می‌شود، صفحه را برای کاربر داخلی کند یا ناقص می‌کند.

برای هر وابستگی، یک جایگزین داخلی

وابستگیجایگزین داخلی
بسته‌های سیستم‌عاملآینه‌ی داخلی با aptly یا apt-mirror
بسته‌های npm، pip و Mavenمخزن واسط مانند Nexus یا Verdaccio که هر بسته را یک بار دریافت و نگه می‌دارد
ایمیج کانتینررجیستری داخلی مانند Harbor با ایمیج‌های پایه‌ی آزموده
زمانسرور NTP داخلی (chrony) که بقیه‌ی دستگاه‌ها از آن همگام شوند
DNSresolver داخلی که درخواست‌ها را به چند مقصد می‌فرستد
هشدارکانالی که از داخل شبکه کار کند، مثل پیامک یا پیام‌رسان داخلی
فونت و اسکریپت سایتمیزبانی روی همان سرور سایت

یک نکته درباره‌ی مخزن واسط: دریافت «هنگام نیاز» کافی نیست. بسته‌ای که هیچ‌وقت درخواست نشده، روز قطعی هم در مخزن نیست. برای وابستگی‌های حیاتی، کل درخت وابستگی را یک بار در روزهای عادی دریافت کنید.

نسخه‌ها را قفل کنید

آینه‌ی داخلی فقط وقتی کمک می‌کند که build دقیقاً بداند چه می‌خواهد. فایل‌هایی مثل package-lock.json، poetry.lock یا go.sum را در مخزن کد نگه دارید و ایمیج‌های پایه را با نسخه‌ی کامل مشخص کنید، نه با برچسبی مثل latest:

FROM registry.internal/base/node:22.12-bookworm

تمرین قطعی

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

  1. یک build کامل از صفر، بدون cache
  2. استقرار یک نسخه‌ی تازه
  3. ری‌استارت یک سرور و یک پایگاه داده
  4. ورود دومرحله‌ای، و بررسی ساعت دستگاه‌ها
  5. ارسال یک هشدار آزمایشی

هر چیزی که شکست خورد، وابستگی‌ای است که در فهرست بالا نبوده. نتیجه را ثبت کنید و تمرین را هر چند ماه تکرار کنید؛ وابستگی‌های تازه بی‌صدا اضافه می‌شوند.

جمع‌بندی

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