Кто ещё выпускаетобновления вашегоприложения?
Тысячи iOS-приложений два часа падали при запуске, хотя их команды ничего не выпускали. Сломались настройки Google Analytics for Firebase. Починили без обновлений — значит, и сломали без них.
В ночь на 29 сентября по Москве у тысяч iOS-разработчиков разом поползли вверх графики падений. Приложения закрывались сразу после запуска. В такой момент в голове один вопрос: что мы выкатили?
Ничего не выкатили. Но искать всё равно начали у себя. Один разработчик, по пересказу Android Authority, успел сжечь кучу токенов, гоняя нейросеть по собственному коду, пока не выяснилось, что код тут ни при чём.
Падало всё внутри Google Analytics for Firebase — библиотеки, которую ставят в приложение, чтобы считать пользователей. Счётчик пользователей перестал пускать пользователей.
2 октября Google выпустил постмортем. Написан он про Google. А рассказал мне больше про то, что мы вообще считаем релизом.
Две строчки и весь мир
SDK аналитики регулярно скачивает с серверов Google настройки — флаги удалённой конфигурации (remote config). Часть из них, пишет Google, работает как аварийные выключатели: если какая-то функция SDK начнёт сбоить, её гасят у всех сразу, без новой версии. Про стоп-краны я уже писал: без них нельзя. Здесь видна другая их сторона. Выключатель — тоже код, и ошибаться он умеет не хуже остального.
28 сентября в 17:38 по калифорнийскому времени инженеры убрали старый ненужный флаг. Плановая уборка. Только в самом SDK осталась ссылка на этот флаг. SDK запросил его, получил пустое имя, не проверил и упал — вместе с приложением, внутри которого жил.
Настройки раскатываются на всех сразу. Через три минуты падения шли по всему миру. Тревога у Google сработала в 17:59, причину нашли в 19:16, откат закончили в 19:52, через два часа одиннадцать минут после начала. Тесты это изменение, кстати, пропустили.
Потом — строчка, которая всех успокоила: обновлять приложения не понадобилось, Google всё исправил у себя на сервере.
Хорошая новость. Только переверните её: если чинить можно без обновления приложения, то и ломать можно без него.
Второй канал
Вспомните, через что проходит ваш код, прежде чем попасть к пользователю. Ревью. Тесты. Сборка. Проверка в App Store, которая иногда тянется днями. Выпуск по частям: сначала проценту людей, потом остальным. Эти ворота строят годами, на них ругаются, их пытаются обойти — и всё равно не убирают: каждые хоть раз кого-то спасли.
Теперь посмотрите, через что прошли настройки Firebase. Через тесты Google, которые ничего не заметили. Всё. Ни вашего ревью, ни проверки в магазине, ни выпуска по процентам. Google сам пишет, что механизм выключателей раскатывается глобально, а поэтапность раскатки ещё только обещает улучшить.
Получается, у приложения два канала выпуска. Первый команда знает, рисует на схемах и охраняет. Второй обычно нигде не нарисован. Через него в приложение приходит чужая логика, и приходит сразу ко всем.
И второй канал не один. Он есть у каждого стороннего SDK, который тянет настройки с сервера, а таких в обычном приложении может набраться несколько: аналитика, реклама, чат поддержки. На сайтах всё ещё откровеннее. Счётчик посещений, виджет онлайн-чата, форма от CRM, кнопка оплаты — это скрипты, которые браузер при каждом открытии страницы берёт с чужого сервера. Что в них сегодня, решает их владелец.
«Процесс выпуска охраняет только ваш код. Всё, что приложение скачивает во время работы, приходит к пользователю без очереди.»
В постмортеме есть деталь, которую легко пропустить. Откат к прежним настройкам в SDK был. После падения он и срабатывал: Google пишет, что каждый пользователь вылетал один раз, а дальше SDK брал старую конфигурацию. То есть страховка была. Она просто стояла после падения, а не вместо него.
Первое, что Google пообещал исправить, ровно про это. Новая версия SDK будет проверять всё, что приходит с сервера, а битый флаг пропускать и брать сохранённые значения. Между «одна функция не обновилась» и «приложение не открылось» здесь ровно одна проверка на пустое имя.
Чьё приложение упало
А теперь та же ночь глазами владельца продукта.
Упало ваше приложение. Не Google. Пользователь видит вашу иконку, ваш вылет и пишет вашей поддержке.
Статус-страницы Firebase и Google Ads все эти часы оставались зелёными. Google это признаёт: они следили за серверными метриками, а падения происходили на телефонах. Новости разработчики узнавали из ветки на GitHub, где отвечали инженеры Google.
А отчёты о падениях доходили с опозданием. Приложение отправляет их, только когда человек откроет его снова. Ту ночь вы видите глазами тех, кто вернулся.
Чужой SDK вы не перепишете. Зато можете перестать делать вид, что его нет.
Первое — опись. Какие библиотеки и скрипты в продукте скачивают во время работы настройки, код или правила. Обычно такого списка нет ни у кого, хотя это ровно та же опись, что у внешних библиотек при проверке перед запуском. Только смотреть надо не на то, что вы поставили, а на то, что оно потом скачивает.
Второе — свой выключатель для чужого кода. Если вспомогательный SDK можно отключить собственным флагом, в следующую такую ночь вы не ждёте два часа, пока кто-то в Калифорнии найдёт причину. Аналитика без пары часов данных переживёт. Приложение, которое не открывается, — вряд ли.
И третье — к собственным удалённым флагам относиться так же, как Google теперь обещает относиться к своим. Битое значение — взять последнее рабочее, а не падать. Новое значение — сначала части пользователей. А удаление старого флага — такое же изменение, как добавление нового.
Флаг, с которого всё началось, был старый и никому не нужный. Его удалили, чтобы стало чище.
- После этого019Закрывает обычно следующийПродукт · 7 мин
- До этого017Пустая проверка теперь стоит денегЗаметка · 4 мин
- На практикеСПРБезопасность кода от ИИ — что проверить перед запуском, если вы не читаете кодРазработка · 8 мин
- На практикеСПРВайбкодинг — что это и можно ли так делать продуктРазработка · 8 мин