Все счастливые семьи похожи друг на друга, каждая несчастливая семья несчастлива по-своему.
«Анна Каренина» Л.Толстой.
Проведя сотни аудитов проектов в IT и расследуя десятки инцидентов, перефразируя классика, можно сказать: «Все проекты счастливы по-своему, а несчастны одинаково». Успех проекта — это уникальное сочетание параметров и людей. А несчастья приносят одни и те же проблемы или совокупность проблем, небольших упущений, которые в итоге приводят к пике. Об одном таком случае сегодня расскажу вам я — эксперт Службы качества SimbirSoft Юлия.
Обычно мало кто реагирует на небольшие отступления от стандартов ведения проектов, соблюдения процессов: «Ничего же страшного не произойдет». Это чревато большими проблемами, когда специалисты не понимают риски, не осознают, зачем то или иное правило, договоренность, и что может произойти в итоге, если этого не делать. Потому что по сути процессы и правила гибкие (в лучших традициях agile :)) Но мелочи и, казалось бы, незначительные вещи на самом деле могут оказать серьезное влияние на весь проект. И привести к катастрофе…

У нас в SimbirSoft есть процесс фиксации и анализа инцидентов. Сначала, конечно, нужно как можно скорее устранить последствия. Но основная цель — понять, почему инцидент произошел и что нужно сделать, чтобы он не повторился в будущем. Как в авиации проводят расследование авиакатастроф, так и у нас в IT — расследование инцидентов, которым занимается, в том числе, служба качества компании (иногда мы в шутку называем себя «следственный комитет»). Но вы не подумайте, допросов с пытками не устраиваем 🙂 Мы в компании развиваем культуру качества, когда можно открыто говорить об ошибках, делать выводы и учиться на них.
Но вернемся к истории об одном инциденте на мобильном проекте, который произошел в конце декабря 2019 года, а после разберем, какие ошибки мы совершили и как их можно было избежать.
26.12.2019
Последняя в году рабочая неделя. Николай, backend-разработчик одного из проектов, давно планировал новогоднюю поездку в Петербург. Остался последний рывок — релиз новых фич.
QA-специалист Гуля написала в чат, что регресс завершен, мелкие баги, которые были, уже поправлены, и пора выкладывать приложение в AppStore и Google Play.
Мобильное приложение для online-тренировок очень нравилось команде: и тренировки, и подход его владельца. Наша компания разрабатывала приложение «под ключ»: от ТЗ, дизайна, архитектуры до иконки в телефоне тех, кто мечтает сделать фигуру мечты. По классике оно состояло из двух частей — серверной и мобильной клиентской (Android и iOS). В команде разработки были аналитик, дизайнер, backend, Android- и iOS-разработчики, QA-специалист и PM. Дрим-тим увлеченных работой и продуктом людей. Приложение уже было в сторах. Первый релиз состоялся 20 октября. И только за первый месяц работы уже было более 50 000 скачиваний, более 4100 оценок и отзывов.
К новому году команда запланировала релиз новых фич и публикацию нового курса тренировок, рекламная кампания которого уже была в самом разгаре. Первые скачавшие получали доступ к тренировкам по сниженной цене и дополнительные видео по мотивации и питанию. Выход продукта ожидала большая аудитория пользователей.
У нас все было готово. Ждали только окончания проверок от AppStore и Google Play.
30.12.2019
PM проекта Анна сообщила заказчику, что приложение успешно прошло проверки и можно проводить релиз.
Клиент решил провести его 31 декабря. Новый год — новая жизнь! А мы были молоды и отчаянны 🙂
31.12.2019
Новая версия стала доступна для пользователей. Пошли скачивания и обновления, все было в штатном режиме. Команда уже делилась планами на новогодние праздники, приводила в порядок таск-трекер и документацию проекта, причесывала бэклог. И спокойно ушла готовить салатики.
19:54 (+3 GMT) Первый алерт о высокой нагрузке на базу данных (БД). Потом еще и еще.
20:35 (+3 GMT) DevOps Максим написал в чат команде о том, что сервер «себя плохо чувствует», и он уже смотрит логи, пытаясь разобраться в произошедшем.
Прочитав сообщения, QA-специалист проекта Гуля сразу зашла в приложение и увидела, что некоторые тренировки не открывались или информация прогружалась длительное время.
PM Анна сидела за новогодним столом, а телефон вибрировал сообщениями: помимо поздравлений там были плохие новости от команды, что приложение не работает, а клиент написал, что возникает ошибка при попытке опубликовать новый курс тренировок.
«Вечер перестает быть томным» 🙂 Новогодний вечер! У клиента 11:00 31 декабря. Разница с командой 8 часов. И срыв выхода нового курса тренировок.
По существующим процессам аккаунт-менеджер Наталья оповестила руководителей компании об инциденте. Несмотря на позднее время и праздник, необходимо срочно спасать релиз.
Backend-разработчик Николай в это время гулял по Санкт-Петербургу — на 30 и 31 декабря он оформил отгул. Но читать рабочие чаты в любое время дня и ночи и даже в отпуске — это зависимость большинства айтишников. Связался с Максом (Devops), и по его описанию возникли подозрения сразу на несколько проблем. Николай написал PM и своему руководителю, указал, что необходимо донастроить кэширование на стороне СУБД.
В команде приняли решение срочно подключить другого backend-разработчика Сергея (представляете его лицо? :)), поскольку Николай не может внести правки. Также решили увеличить производительность сервера.
21:53 (+3 GMT) На экране приложения появилось сообщение «Ошибка приложения». Бэк полностью «умер».
22:46 (+3 GMT) Кэширование уже на проде, «железные» мощности тоже уже добавили. Приложение «завелось». Но стало понятно, что это временная передышка и лишь возможность выиграть время на поиск и исправление проблемы. Кэширование и увеличение производительности сглаживали ситуацию, но не решали ее.
00:00 (+3 GMT) С Новым годом!
Да-да, каждый член команды праздновал у компа или телефона, чтобы в любой момент подключиться при необходимости!
1.01.2020
Сергей нашел основную проблему приложения и уже вносил правки, попутно консультируясь с Николаем.
Исправленный код на тесте. QA-специалист оперативно подключилась и проверила, нашла пару замечаний. Снова правки и снова тест. Потом мини-регресс (да-да, именно мини, пошире смоука, но времени на полноценный нет).
02.01.2020
Все исправления на проде. Можно было выдохнуть, но все же нужно было еще понаблюдать за нагрузкой на СУБД.
03.01.2020
Проблемы с кэшем Redis. Приложение было недоступно в ночное время у клиента, проблему удалось решить сбросом кэша.
04.01.2020
18:40 (+3 GMT) Приложение упало на 3 минуты, произошел сброс кэша пользователей, сделали новый вариант сброса и работы кэша.
05.01.2020
Мониторинг без аномалий. Полет нормальный. Выдохнули. Поставлена задача реализовать API 2.0.
9.01.2020
В первый рабочий день после новогодних праздников PM Анна сделала новую запись в трекере инцидентов о проблемах в работе приложения после выпуска в продакшен.
Служба качества собрала рабочую группу по расследованию инцидента: необходимо было провести технический анализ допущенных ошибок, установить причины их появления, выработать алгоритм действий для недопущения подобной ситуации в будущем.
25.02.2020
Релиз обновленного приложения. Были доработаны и бэк, и мобильное приложение (Android, iOS). Единый запрос на всю структуру тренировок был разбит на несколько, в соответствии с уровнями вложенности. Прогресс по тренировкам тоже «ушел» в отдельные роуты.
Команда провела нагрузочное тестирование с использованием примеров новых, более сложных по структуре данных тренировок.
Последующие новые фичи — бесплатные тренировки, анонсы, мультиязычность — уже проходили гладко, без эксцессов и сложностей.
Допущенные ошибки, и как их можно было избежать
1. Неправильное построение запросов
PM предположила, что заниматься спортом по тренировкам из приложения пользователи могут в местах, где не очень хорошая связь (привет тренажеркам в подвалах от детей 90-х :)). Backend-разработчик согласился на предложение PM сделать один большой запрос на загрузку всей информации о всех тренировках, не предполагая, насколько после возрастут объемы загружаемой информации. Это упростило работу мобильным разработчикам, но нарушило принцип REST — вместо множества GET-запросов для получения разных уровней вложенности тренировок, был один запрос, загружающий сразу все уровни.
Кроме структуры курсов, ответ от этого запроса содержал и прогресс пользователя по тренировкам, то есть ещё дополнительные запросы к базе. К тому же само получение структуры тренировок добавило проблему N+1 из-за использования ленивых ассоциаций.
Этого не было видно на тестовых данных. Однако на проде проблема расцвела во всей красе.
Как надо было сделать:
При наличии иерархических моделей данных в ответе на запрос получения данных любой модели не должна содержаться информация о дочерних ресурсах. Каждой модели данных должен соответствовать свой путь. Backend-разработчик должен был отстоять свое мнение, привести аргументы. А еще лучше — совместно с командой сформировать плюсы и минусы двух решений, возможные риски. И уже на основе этой информации принимать решение.
2. Тестовые данные не соответствовали реальным
Вложенная структура данных реальных тренировок оказалась в несколько раз сложнее, чем мы представляли. Один большой запрос с такой сложной многоуровневой структурой оказался фатальным для производительности приложения.
Примеры тренировок от заказчика для тестирования данных оказались намного проще, чем реальные тренировки, которые были потом введены в приложении.
Как надо было сделать:
-
Всегда запрашивать примеры тестовых данных. Чем больше, тем лучше. Но не единоразово. Если есть планы по новым фичам, то важно запрашивать их повторно. В нашем случае необходимо было запросить пример нового курса тренировок.
-
Определить ограничения по типу, объему, структуре данных. Согласовать с командой и клиентом.
По возможности провести тестирование как на простых, так и на усложненных примерах. Понимаю, что чаще всего время на тестирование ограничено, поэтому здесь действуем без фанатизма.
-
Задавать наводящие вопросы: «А какие еще в перспективе могут быть изменения в приложении?», «Планы по развитию?», «Как это отразится на данных?».
3. Не было реализовано закрытие соединения к Redis
В явном виде не было закрытия соединения, само закрывалось, но долго висело. Реализация функциональностей базировалась на документации Symphony и по сути реализовывалась «в лоб», без углубления в особенности работы фреймворка и доктрины.
В первой итерации исправления проблем приложения увеличили производительность сервера и расширили кэширование — вся структура тренировок заносилась в кэш. Это помогало, но не в полной мере. Так как при любых изменениях структуры тренировок в админке весь кэш группы тренировок сбрасывался, пока он формировался заново, часть пользователей могли получать ошибки. Поэтому мы добавили прогрев кэша. После этого приложение стало работать стабильнее, а мы продолжили последовательную работу по исправлению.
Как надо было сделать:
Этот пункт возник из-за первых двух и экстренных правок. Правильно выстроить работу с кэшем и подсветить первые две проблемы позволило бы своевременное проведение нагрузочных тестов.
Что в итоге мы изменили у себя в процессах
-
Ввели архитектурный надзор в каждом производственном направлении разработки. Проводим ревью разрабатываемой архитектуры на контрольных точках проекта, которые определяют PM.
-
При тестировании фокусируемся на релевантных тестовых данных. Актуализируем примеры при разработке новых фич.
-
На каждом проекте обязательно анализируем необходимость проведения нагрузочных испытаний. Разработали чек-лист для выявления требований по производительности, шаблон требований к производительности и нагрузке.
-
Для обеспечения требуемых параметров производительности продукта проводим минимальные нагрузочные испытания, даже если клиент считает, что в них нет необходимости.
-
Ввели мораторий на релизы в предпраздничные дни и по пятницам.
Что могу сказать в заключении. Когда я села писать историю об этом кейсе, у меня даже мысль возникла: «А как мы это упустили? У нас же есть контроль на уровне архитектуры и сбора требований». А потом поняла — да это же как раз после этого инцидента ввели :)))
Разработка без ошибок — это в идеальном мире. Самое главное — делать выводы, учиться на ошибках и непрерывно улучшать процессы создания программных продуктов. Всем добра!
Спасибо за внимание!
Больше полезных материалов для разработчиков и управленцев в IT мы также публикуем в наших соцсетях – ВК и Telegram.
ссылка на оригинал статьи https://habr.com/ru/companies/simbirsoft/articles/740618/
Добавить комментарий