MAATRIX / Блог / TTL 86400 превратил пятиминутный переезд в двухдневный

TTL 86400 превратил пятиминутный переезд в двухдневный

MAATRIX

Переезд планировали на один вечер: поднять новый сервер, перелить данные, переключить A-запись, проверить — и разойтись. По факту часть посетителей ещё двое суток попадала на старый сервер, который к тому моменту уже не принимал заказы и не обновлял данные. Разбираемся, как безобидное значение TTL, оставшееся с дефолтных настроек, превратило контролируемый cutover в затяжной инцидент с рассинхроном данных.

Как выглядела картина в первые часы

План был обычный: новый сервер настроен, приложение развёрнуто, база перелита финальным дампом, оставалось переключить DNS-запись домена с IP старого сервера на IP нового. Запись поменяли в панели регистратора в 22:00, дождались, что dig с локальной машины отдаёт новый IP, и посчитали переезд завершённым.

Утром картина была странной: часть пользователей писала, что сайт работает и всё нормально, часть — что видит старую версию без вчерашних изменений, а часть жаловалась, что не может оформить заказ, потому что данные о товаре не совпадают с тем, что показывает поддержка. Метрики нагрузки на новом сервере росли, но недостаточно быстро — трафик явно шёл не туда.

Проверка curl -v https://example.com с разных сетей (мобильный интернет, домашний провайдер, VPS в другом регионе) показывала разные IP в ответ на один и тот же домен. Кто-то уже общался с новым сервером, кто-то всё ещё стучался в старый. Split-brain по факту — два продакшена одновременно, и это самое неприятное состояние, потому что заказы, регистрации и правки контента расползаются по двум базам, которые уже не синхронизируются.

Что показали логи и метрики

На старом сервере в access-логах nginx трафик не упал до нуля сразу после смены записи — он снижался плавно, растянувшись почти на двое суток вместо ожидаемого падения за час-два:

# на старом сервере, спустя 20 часов после смены A-записи
tail -f /var/log/nginx/access.log | grep -c "GET / HTTP"
# всё ещё десятки запросов в минуту

На новом сервере графики запросов в секунду росли не скачком, а пологой кривой — классическая картина постепенного «доверивания» резолверов новому адресу, а не мгновенного переключения.

Проверка через dig +trace example.com с разных резолверов (Google 8.8.8.8, Cloudflare 1.1.1.1, DNS провайдера) сразу показала разброс: у одних уже новый IP, у других — старый, у третьих ответ вообще пришёл из локального кэша с TTL под 60000+ секунд, оставшимся с прошлого запроса.

dig @8.8.8.8 example.com +noall +answer
example.com.  43211  IN  A  203.0.113.10   # старый IP, TTL всё ещё тикает

Число 43211 в TTL — это буквально секунды, оставшиеся до того, как резолвер обязан обратиться за свежим ответом. И оно почти совпадало с временем, прошедшим с последнего опроса резолвером старой записи до момента изменения.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Гипотеза первая: опечатка в новой A-записи

Первым делом заподозрили банальную ошибку — вдруг в панели регистратора вбит не тот IP, лишний пробел, не тот тип записи (AAAA вместо A), не применились изменения из-за кэша в самой панели. Проверили запись напрямую через API регистратора и через dig к авторитетным NS домена (не к публичным резолверам, а именно к NS, прописанным в делегировании):

dig @ns1.registrar-dns.com example.com A +short
203.0.113.55   # новый IP, всё верно

Авторитетные серверы отдавали правильный, новый адрес с первой секунды после сохранения изменений. Гипотеза отпала: запись была верной, проблема была не в том, что написано, а в том, кто и когда это увидит.

Гипотеза вторая: проблема на стороне нового сервера

Вторая версия — может, новый сервер не отвечает стабильно, и часть запросов до него не доходит, из-за чего клиенты откатываются на старый по DNS-failover или ретраям в браузере. Проверили нагрузочными запросами напрямую по IP, минуя DNS:

curl -o /dev/null -s -w "%{http_code} %{time_total}\n" --resolve example.com:443:203.0.113.55 https://example.com
200 0.084

Сервер отвечал стабильно, TLS-сертификат (уже выпущенный на новый IP через certbot) проходил проверку, приложение и база работали штатно под нагрузкой. Значит, дело не в новом сервере — он был готов принимать весь трафик с первой минуты. Проблема была где-то между DNS-записью и клиентами.

Настоящая причина: TTL 86400 и как резолверы на самом деле кэшируют

У A-записи домена стоял TTL 86400 секунд — ровно сутки. Это значение осталось от изначальной настройки зоны и никто не трогал его годами, потому что домен не переезжал. Когда TTL такой большой, каждый резолвер, который успел спросить адрес домена до момента смены записи, имеет полное право не обращаться за новым ответом ещё до 24 часов — и правило TTL это не рекомендация, а часть протокола DNS, которую резолверы обязаны соблюдать.

Проблема усугубилась на практике сильнее, чем в теории, по нескольким причинам:

  • Не все резолверы одинаково честны с TTL. Часть корпоративных и провайдерских DNS-серверов кэширует ответы дольше заявленного TTL или дольше положенного из-за собственных настроек производительности — это ловится опытом, а не документацией, но случай был не единичный: у нескольких пользователей адрес не обновился и после того, как TTL по расчётам должен был истечь.
  • Браузеры и ОС держат собственный DNS-кэш поверх резолвера — Windows, macOS, некоторые мобильные ОС кэшируют ответ ещё раз, независимо от системного резолвера, и живут по своим таймаутам.
  • Мобильные операторы и корпоративные сети часто имеют один резолвер на тысячи абонентов — если этот резолвер опросил домен за минуту до смены записи, все клиенты за ним получают старый IP ещё почти сутки, и это не единичный пользователь, а целый пул трафика разом.

Проверка через публичный сервис DNS-checker (наблюдение за ответом с десятков точек мира) подтвердила: часть резолверов действительно отдавала новый IP почти сразу, а часть — держала старый ещё 20+ часов, что суммарно и дало эффект «переезда на двое суток» вместо ожидаемых минут. TTL 86400 — это верхняя граница, к которой добавляется реальное поведение конкретных резолверов, и на практике она может быть даже больше заявленной.

Что сделали, чтобы не потерять данные во время затянутого cutover

Раз мгновенно откатить всех на новый сервер было нельзя, а два продакшена одновременно — это риск потери заказов и рассинхрона контента, приняли решение временно превратить старый сервер в reverse-proxy на новый, а не выключать его резко:

# конфиг на СТАРОМ сервере — временный мост на новый, пока не истечёт TTL у всех резолверов
server {
    listen 80;
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass https://203.0.113.55;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_ssl_server_name on;
    }
}

Это сразу убрало главную боль — рассинхрон данных: независимо от того, какой IP отдал резолвер конкретному пользователю, все запросы физически обрабатывались одним и тем же приложением и одной базой на новом сервере. Старый сервер стал прозрачной трубой, а не отдельным продакшеном. База данных на старом сервере была остановлена и переведена в read-only, чтобы исключить случайную запись мимо основного хранилища.

Параллельно снизили TTL записи до 300 секунд сразу же, как поняли масштаб проблемы — это не решило уже закэшированные у части резолверов записи, но ускорило обновление для всех, кто на тот момент ещё не успел закэшировать старый ответ, и подготовило зону к более быстрому переключению в будущем.

Мониторили ситуацию через логи обоих серверов и через периодический опрос публичных резолверов по всему миру, чтобы понимать, когда доля запросов на старый IP реально упадёт до нуля, а не гадать на глаз.

Что изменили в процессе миграций на будущее

Главный вывод — TTL нужно снижать заранее, а не в момент переключения, потому что снижение TTL само по себе требует времени на распространение по тому же принципу, по которому распространяется смена IP.

КогдаЧто делать с TTLЗачем
За 3-7 дней до переездаСнизить TTL A-записи до 300 секундДать старому TTL (например, 86400) истечь у всех резолверов заранее
В день переездаМенять A-запись при TTL уже 300 секРезолверы обновятся в пределах нескольких минут после отработки нового TTL
После подтверждения полного переключения (обычно 24-48 часов наблюдения)Вернуть TTL к обычному значению (3600-86400)Снизить нагрузку на авторитетные NS-серверы в штатном режиме

Дополнительно завели чек-лист для будущих переездов:

  • Перед переездом проверять текущий TTL всех задействованных записей (A, AAAA, CNAME, MX при необходимости) через dig к авторитетным NS, а не полагаться на память или документацию годичной давности.
  • Держать старый сервер в режиме proxy минимум столько времени, сколько было заявлено в TTL до его снижения, плюс запас на нечестные резолверы — на практике это одни-двое суток даже при формально коротком TTL.
  • Не выключать и не удалять старый сервер физически, пока мониторинг не покажет ноль запросов подряд в течение нескольких часов, а не единичный нулевой снэпшот.
  • Проверять переключение не только со своей рабочей машины (велик шанс, что ваш локальный резолвер уже обновился раньше всех), а с нескольких независимых точек — мобильная сеть, другой провайдер, VPS в другом регионе.

Если переезд связан не только со сменой IP, но и с полным переносом инфраструктуры между локациями, стоит заранее прикинуть план миграции на новый сервер целиком, а не рассматривать DNS как последний технический шаг — на практике именно TTL и его хвосты чаще всего рвут расписание. Похожий эффект «сайт открывается со старого сервера» разбирали отдельно применительно к ситуации после переноса без учёта DNS-кэша, а типовые сбои именно DNS после переезда собраны в материале про проблемы с DNS после переезда.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли заранее узнать, сколько реально продержится старый IP в кэшах, если TTL не снижали заранее?

Точно — нет, потому что часть резолверов не соблюдает TTL строго и держит ответы дольше заявленного. Ориентируйтесь на заявленный TTL плюс запас минимум в сутки для непредсказуемых резолверов, и держите старый сервер живым (хотя бы как прокси) весь этот срок.

Что если снизить TTL прямо перед переездом, а не за несколько дней?

Это не поможет — старое, ещё не сниженное значение TTL уже закэшировано у резолверов, которые опросили запись до изменения. Новый (короткий) TTL начнёт работать только для тех, кто спросит запись уже после снижения, поэтому снижать нужно заранее и ждать, пока пройдёт старый интервал.

Обязательно ли делать reverse-proxy на старом сервере, или можно просто оставить старую версию сайта работать несколько дней?

Если приложение работает с базой данных и принимает заказы или регистрации, оставлять старую версию активной опасно — данные разъедутся между двумя базами. Проксирование на новый сервер решает это, потому что все запросы физически попадают в одно и то же приложение и хранилище независимо от того, какой IP отдал резолвер.

Как быстро проверить, у какого TTL стоит сейчас конкретная запись?

dig example.com A и посмотреть на число в столбце TTL строки ответа — это секунды, оставшиеся до истечения текущего кэшированного значения у конкретного резолвера, а не постоянная настройка зоны (саму настройку зоны лучше смотреть у авторитетных NS через dig @ns1.example-registrar.com).

Нужно ли снижать TTL и для MX-записей, если переезжает только веб-сервер?

Если почта остаётся на прежнем сервере или у стороннего провайдера, MX-записи можно не трогать — снижать TTL стоит только у тех записей, которые реально меняются в рамках переезда.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →