Блог

Неудачная повторная публикация никогда не удаляет работающий бэкенд

25 сентября неудачная повторная публикация удалила бэкенд приложения, который примерно два с половиной часа работал без сбоев. Код, который откатывает неудачную публикацию, удалял все серверные приложения, которых коснулась публикация, включая те, что уже обслуживали пользователей до её начала. Теперь удаляются только приложения, которые создала сама публикация. Приложение, которое уже существовало, возвращается к той версии, которая работала до публикации. Два последующих исправления в тот же день гарантировали, что откат запускается даже тогда, когда сломался собственный инструмент деплоя хостинг-платформы, и что здоровое приложение не помечается как неисправное только потому, что оно спало.

Как публикуется бэкенд

Если у вашего приложения Mythex есть бэкенд, то есть API или сервер, а не только статические файлы, публикация собирает его из Dockerfile (рецепта упаковки приложения в образ) и разворачивает этот образ на машинах нашей хостинг-платформы. Затем проверка работоспособности ждёт, пока новая версия действительно запустится и будет стабильно работать, и только после этого публикация отмечается как активная.

Если на каком-то этапе что-то падает, запускается откат, который всё отменяет. Правильно сделанный откат важнее почти всего остального в публикации, потому что он срабатывает именно тогда, когда уже что-то идёт не так.

Проблема 1: откат удалял то, что должен был восстановить

Откат вёл список серверных приложений, на которые развернула публикация, и при ошибке уничтожал каждое из них. Для первой публикации это правильно: приложение только что создано, ничто от него не зависит, и удаление возвращает всё в исходное состояние.

Для повторной публикации это как раз неверно. Приложение уже существовало и обслуживало реальных посетителей. 25 сентября неудачная повторная публикация удалила API приложения, которое работало около двух с половиной часов.

В том же коде пряталась и вторая проблема. Если удаление не проходило, сломанный новый образ оставался на машинах, а мы при этом сообщали владельцу, что его сайт всё ещё работает. К тому моменту, когда проверка работоспособности может провалиться, новый образ уже развёрнут на всех машинах. Ничего не делать — не то же самое, что откатить.

Исправление: удалять только то, что создано, а остальное восстанавливать

Теперь каждая публикация записывает для каждого затронутого серверного приложения:

  • создала ли эта публикация его, и
  • если нет, какой образ оно запускало непосредственно перед этим.

При ошибке каждое приложение получает один из трёх вариантов обработки:

  1. Создано этой публикацией: удалить, как и раньше.
  2. Уже существовало, предыдущий образ известен: развернуть предыдущий образ с той же конфигурацией. Сборки нет, возвращается только образ.
  3. Уже существовало, предыдущий образ неизвестен: не трогать. Существующее приложение никогда не удаляется, даже если его не удаётся восстановить.

Эти правила написаны как небольшая чистая функция с собственными тестами, поэтому решение не может незаметно вернуться к «удалить всё» без того, чтобы тест упал.

Проблема 2: инструмент деплоя мог упасть раньше, чем мы записали, как откатить

Вскоре после этого исправления мы нашли в нём пробел. Инструмент деплоя хостинг-платформы запускает собственные дымовые проверки: если новые машины падают, он завершается с ошибкой. Но делает он это уже после того, как новый образ оказался на машинах.

Наш код регистрировал приложение для отката только после того, как инструмент успешно завершался. Когда сам инструмент проваливал деплой, приложения ещё не было в списке отката, и ничего не восстанавливалось. На нашем тестовом окружении сломанная повторная публикация оставила в работе сломанный образ.

Исправление: зарегистрировать откат до начала

Теперь приложение регистрируется для отката, с признаком создано ли оно и каким образом оно работало, как только подготовлено и до того, как на него что-либо развёрнуто. Что бы ни сломалось дальше, откат знает, что возвращать. Мы проверили это локально: сломанная повторная публикация провалилась на собственных дымовых проверках инструмента деплоя, и предыдущая версия продолжала отвечать.

Проблема 3: спящее приложение пометили как «так и не запустилось»

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

25 сентября этот единственный запрос на запуск не сработал. Здоровый API простоял остановленным всё пятиминутное окно проверки и был помечен ошибкой «1 машина так и не запустилась (последнее состояние: stopped)».

Платформа иногда действительно отказывает в запуске. Во время воспроизведения проблемы она без нашего вмешательства вернула конфликт «lease currently held», а также отказывает в запуске, пока машина обновляется.

Исправление: продолжать спрашивать и постучаться в дверь

Теперь проверка работоспособности:

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

Мы воспроизвели это на реальной платформе с временным приложением, первый запуск которого был отклонён. До исправления публикация падала через 91 секунду. После исправления она публиковалась за 20 секунд. Приложение, которое действительно падает при загрузке, по-прежнему проваливается, как и должно.

Что мы вынесли из этого

  • Откат должен различать новое и существующее. «Отмена» для созданного вами — это удаление. «Отмена» для уже существовавшего — это восстановление. Когда оба случая обрабатываются одинаково, защитный механизм и удаляет работающее приложение.
  • Запишите, как откатить, прежде чем действовать. Если отмена фиксируется только после успешного шага, шаг, который упал на полпути, оставляет нечего отменять.
  • Никогда не игнорируйте ответ на запрос, от которого вы зависите. Один проигнорированный отказ превратил здоровое приложение в неудачную публикацию.

Связанное исправление того же дня: что делать, когда приложение падает сразу после публикации. О том, что происходит, когда публикация падает по вине нашей стороны, читайте устранение неполадок публикации в документации.

Mythex · Pricing · Создавайте что угодно с ИИ · Шаблоны сайтов и приложений · Сравнения Mythex · Глоссарий по созданию приложений с ИИ · Бесплатные инструменты для создания приложений с ИИ · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)