Не стреляйте в жонглеров, им и так стыдно: как серия проколов привела нас к улучшению процесса контроля качества

“Хороший программист — это тот, кто смотрит в обе стороны, переходя дорогу с односторонним движением”.
Даг Линдер

Есть расхожая присказка о программировании. Мол, программирование - это легко, как кататься на велосипеде. Который горит. И ты горишь. И все кругом горит. И ты в аду.

То же справедливо и для разработки софта в целом, за исключением одной детали. В этом случае разработчики еще и жонглируют на ходу десятком вещей, от резиновых мячиков до заведенной “Дружбы” и парочки шимпанзе.

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

Матерые жонглеры научились держать в уме траектории своих предметов и следить за коллегами боковым зрением, развили звериную реакцию и инфернальное чутье. Но как и в любом другом деле, путь к мастерству лежит через ошибки. Я хочу показать на примере отдельно взятого продукта, как училась жонглировать наша команда.

Речь пойдет о QA системы, которая прогнозирует открутку рекламных кампаний на площадке клиента. Система моделирует кампании с учетом всех кастомных параметров и тут же рассчитывает, получится ли выполнить контракт с рекламодателем и как для этого подправить таргетинг.

Много лет назад, когда я только пришел в команду, меня приятно удивило, насколько здорово ребята наладили контроль качества. Почти весь UI функционал был покрыт автотестами, разработчики исправно писали юнит-тесты и интеграционные тесты. Неавтоматизированные кейсы проверялись вручную с помощью формализованных тест-кейсов. Новые фичи тестировались еще на ранних этапах разработки.

Я, пришедший из компании, где ничего такого не было, глядел на эти чудеса прогресса широко раскрытыми глазами, как неандерталец, попавший на борт космического корабля. Какие проблемы могут возникнуть с таким продвинутым контролем качества? Процессы казались идеальными, а будущее — безоблачным.

Январь 2018. “Ребята, у нас проблемы на проде”.

С этой нехитрой фразы начался один жаркий рабочий день. Команда сработала хорошо, работоспособность системы восстановили быстро, а причина оказалась неожиданной.

Клиент продает рекламные показы через рекламный сервер. Мы интегрируемся с этим сервером через API, выгружаем данные о проданных показах и строим по ним прогноз.

Каждое утро, до начала рабочего дня, система обучается: обновляет данные о показах через API и совершенствует расчеты. Во время обучения прогнозирование недоступно, и это является нормой.

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

Тогда мы написали автоматизированные проверки — хелсчеки продакшн систем — для каждого из клиентов. Сразу после обучения они начинали проверять доступность прогнозирования через API и UI. Если система не успевала рассчитать прогноз за установленное время, хелсчеки отправляли алерт в канал поддержки в Slack.

Вывод: контроль качества не заканчивается после того, как система поставлена клиенту. В каждый момент времени мы должны быть в курсе текущего состояния системы.

Март 2018. “Ребята, у нас снова форкаст не работает на проде”.

Ощущение дежавю спустя несколько месяцев после предыдущего инцидента. Да как так-то? Хелсчеки молчат, все в порядке, кроме настроения клиента.

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

Полезли разбираться, почему промолчали хелсчеки, и обнаружили, что наш CI/CD сервер Teamcity, на котором они запускались, горестно стоит без единого билдагента (машины, выполняющей задания CI/CD-сервера), а хелсчеки радостно набились в очередь.

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

После этого разработчики научили приложения отправлять метрики в Graphite, админы подняли Grafana и помогли настроить оповещения. Теперь, если вдруг хелсчеки переставали приходить, Grafana заботливо сообщала: “Ребята, у вас тут проблема”. Воцарился мир и спокойствие.

Вывод:

  1. Если нет оповещения о наличии проблемы, это не значит, что проблемы нет.
  2. Если нет оповещения об отсутствии проблемы — проблема однозначно есть.

Апрель 2018. “Ребята, у вас тут система недоступна,”

— с этими словами обратился к нам клиент. Отчаянно краснея, мы строго посмотрели на хелсчеки — все в порядке. Проверили систему руками — все в порядке. Проверили доступность системы из внешней сети - вуаля! Глухо, как в танке, система недоступна.

Команда инфраструктуры, поднятая по тревоге, рапортует о том, что Роскомнадзор в борьбе с Telegram ведет огонь по площадям, и айпишники части наших машин попали в заблокированный диапазон.

Поминая РКН незлым тихим словом, команда инфраструктуры потушила пожар, а наша команда заключила, что держать хелсчеки и проверяемую систему в одной сети неразумно. Так у нас появились дополнительные проверки доступности системы из разных точек мира.

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

Сентябрь 2018. Минздрав предупреждает: алерты вызывают привыкание

Интеграция с graphite манила и зачаровывала, и разработчики начали складывать в него все больше метрик. А с каждой новой метрикой копилось все больше алертов с диапазоном критичности от “да так, ерунда” до “О НЕТ, МЫ ВСЕ УМРЕМ, ЧИНИ СКОРЕЕ”.

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

  1. Самые критичные проблемы, которые влияют на работу клиента в системе, искажают расчеты и т.д. — то, что требует немедленной реакции.
  2. Проблемы, которые не требуют немедленного решения, но рискуют через несколько дней дорасти до первой группы.
  3. Сообщения о замеченных аномалиях в данных или о нетипичных значениях вторичных метрик. Здесь мы ловим еще только зарождающиеся проблемы, которые через недели и месяцы могли бы разрастись до размеров вулкана.

На каждый алерт мы написали плейбук — пошаговое руководство о том, как решить проблему и кому ее эскалировать, если сценарий из плейбука не помог.

Также мы внедрили систему Opsgenie, которая звонит и шлет смски с описанием проблемы дежурному инженеру. Если инженер по каким-то причинам не реагирует — она дергает других людей до тех пор, пока кто-то не займется проблемой.

Параллельно мы начали планомерный отказ от старых систем мониторинга: Zabbix, Sentry и кастомных алертов на почту - с удивлением обнаружив, что инженеры поддержки совершенно не рады мониторить несколько разных систем.

Вывод:

  1. Метрики состояния системы помогают обнаружить зачатки проблем.
  2. Бесконтрольный поток алертов помогает упустить критичные проблемы.
  3. Нужно ограничить число каналов оповещения, структурировать поток алертов и прописать алгоритм действий при нештатных ситуациях.

Вместо заключения

Что мы приобрели в результате (не считая паранойи)?

Сделали экосистему продукта значительно стабильнее.

Научились контролировать качество продукта уже после его поставки клиенту, разворачивать качественные проверки на качественной инфраструктуре, продумывать ситуации вида “а что будет, если эта проверка не сработает?”

Наконец, научились делать правильные выводы из ошибок.

И самое главное — мы стали работать на опережение: предугадывать проблемы в продакшене и перекрывать возможные риски автоматизированными проверками.

Все предусмотреть невозможно, однако мы продолжаем последовательно отвоевывать территорию у ее величества Неопределенности.

Павел 
Киселев
Павел КиселевРуководитель отдела качества