Публикация и обновления
почему старая версия живёт дольше, чем кажется
Что это
Публикация — это не финал, а начало состояния, в котором у твоей программы одновременно несколько версий. Сервер обновился, а приложения у пользователей нет. Сайт обновился, а в браузере лежит старый файл. Новая версия в магазине, а половина людей на прошлогодней.
Поэтому главный вопрос при каждом обновлении не «как выложить», а «что будет с теми, кто ещё на старой». Этот вопрос не задаёт ни ИИ, ни инструменты публикации — его задаёшь только ты.
Как выглядит в коде
Три способа публикации — три разных скорости
| Что публикуем | Как попадает к людям | Можно откатить |
|---|---|---|
| сайт | мгновенно, при следующем открытии | да, мгновенно |
| сервер, API | мгновенно, всем сразу | да, если готовился |
| приложение в магазине | после проверки, по желанию людей | нет |
Разница в последнем столбце — самая важная. Сайт откатывается за минуту. Приложение в магазине откатить нельзя: можно только выпустить следующую версию и ждать, пока её поставят. Поэтому и проверяют мобильные сборки тщательнее, и раскатывают их на часть пользователей, а не на всех сразу.
Сайт: кэш, и как сборка его обходит
Собираем проект два раза подряд, не меняя ни строчки:
$ npx vite build
dist/assets/index-Dg-DehUb.js 222.57 kB │ gzip: 69.34 kB
$ npx vite build
dist/assets/index-Dg-DehUb.js 222.57 kB │ gzip: 69.34 kBИмя файла одно и то же. Теперь меняем в тексте одно слово и собираем снова:
$ npx vite build
dist/assets/index-BKJJYt4K.js 222.59 kB │ gzip: 69.36 kBИмя изменилось. Эти буквы в имени — отпечаток содержимого: другое содержимое — другое имя. Сделано это ровно для одной цели: чтобы браузер, который держит файлы у себя, не подсунул пользователю старый код. Старый файл в кэше никому не мешает — за ним просто больше никто не придёт.
Но один файл в этой схеме имени не меняет:
dist/index.html 0.39 kB
dist/assets/index-BKJJYt4K.js 222.59 kBindex.html — тот самый файл, в котором написано, какой из хэшированных
файлов загружать. Его кэшировать нельзя. Если хостинг закэширует
index.html на сутки, пользователь сутки будет открывать старую страницу,
ссылающуюся на старый код, и никакая публикация этого не исправит.
Отсюда правило настройки хостинга, которое стоит знать наизусть: файлы с
хэшем в имени — кэшировать надолго, index.html — не кэшировать. Это
единственная настройка, которую стоит проверить руками при первой публикации
сайта.
Сервер: обновление задевает тех, кого не ждали
Сервер обновляется мгновенно и для всех. И вот здесь вылезает то, о чём не думают: у старых приложений на телефонах нет кнопки «обновись сейчас».
Переименовали поле в ответе API — приложения, выпущенные полгода назад, перестали показывать погоду. Сделали поле обязательным в запросе — старые версии перестали отправлять данные. Формально ты поменял свой сервер; реально ты сломал программы, которые уже стоят у людей.
Правило, которое из этого следует:
- добавлять поля можно, старые клиенты их просто не заметят;
- удалять и переименовывать — нельзя, пока живы те, кто ими пользуется;
- если изменение неизбежно — рядом появляется
/api/v2/, а/api/v1/продолжает работать (статья 7.3).
Второе, что ломается на сервере, — база данных. Обновление базы и обновление кода происходят не одновременно, и порядок имеет значение: сначала добавляется новое поле, потом выкладывается код, который им пользуется. В обратном порядке получится несколько минут, в которые код ищет то, чего ещё нет.
И третье: откат кода — дело одной команды, а откат изменений в базе — нет. Удалённый столбец не вернётся вместе с откатом. Поэтому изменения базы, которые что-то удаляют, выкладывают отдельно и позже, когда уже понятно, что новая версия живёт.
Магазин: что происходит после загрузки
загрузили → проверка → доступно части людей → доступно всемПроверка занимает от часов до дней и может закончиться отказом. Самые частые причины отказа не технические: разрешения без объяснения (статья 12.2), нерабочая демонстрация для проверяющего, отсутствие политики конфиденциальности, если приложение собирает хоть что-нибудь.
Поэтапная раскатка — выдать новую версию сначала небольшой доле пользователей — единственная защита от того, что откатить публикацию нельзя. Если в первые сутки посыпались падения, раскатку останавливают, и большинство людей так и остаётся на работающей старой версии.
Как сказать ИИ
Публикация — это та область, где от ИИ полезнее всего получать списки проверок, а не действия.
Я меняю ответ API: поле "temp" становится "temperature".
Мои мобильные приложения в магазине обновляются не сразу.
Что сломается у тех, кто на старой версии?
Предложи способ сделать это изменение без поломки.Я добавляю в базу обязательное поле. Напиши порядок
действий: что выкладывать первым, что вторым и что
произойдёт, если выложить в обратном порядке.
Отдельно: какая часть этого не откатывается.Второй запрос стоит задавать всегда, когда меняется база. Ответ на вопрос «что не откатывается» — это и есть список того, что надо делать осторожно.
Вот настройки кэширования моего хостинга: <настройки>.
Файлы сборки имеют хэш в имени, index.html — нет.
Что настроено неправильно и к чему это приведёт?Составь чек-лист публикации для моего проекта: <описание>.
Раздели на «до публикации», «сразу после» и «через сутки».
Только то, что относится к моему стеку.На что смотреть
Изменение API без мысли о старых клиентах. Поле переименовано, версия не добавлена. Работает у тебя, сломано у тех, кто не обновился.
Удаление в базе одной выкладкой с кодом. Откат станет невозможным ровно в тот момент, когда понадобится.
index.html кэшируется. Публикации перестают доходить до пользователей, и
причину ищут в коде.
Нет способа узнать, что сломалось. После публикации нужны логи и сообщения об ошибках, иначе о поломке сообщат пользователи — или не сообщат.
Публикация делается руками и по памяти. Пока это пять команд в терминале, которые ты помнишь, — однажды ты выполнишь их в другом порядке.
Версия не видна в приложении. Когда пользователь жалуется, первый вопрос — какая у него версия. Если её негде посмотреть, разговор не состоится.
Миграция без проверки на копии данных. Запуск изменения структуры сразу на настоящей базе — самый дорогой из возможных способов узнать, что в нём ошибка.
Шпаргалка
После публикации версий всегда несколько: думай о тех, кто на старой.
Сайт откатывается мгновенно, сервер — если готовился, приложение — никогда.
Хэш в имени файла — защита от кэша;
index.htmlкэшировать нельзя.«Старое в браузере» — проверь инкогнито, прежде чем искать в коде.
В API можно добавлять, нельзя удалять и переименовывать.
Сначала поле в базе, потом код; удаления — отдельно и позже.
Откат кода есть, откат базы — нет.
Раскатывай на часть пользователей и не публикуй в пятницу.