Mail.ru Group
3 583

Опыт Ситимобил: как мы повышали стабильность сервиса, который вырос в 15 раз

Быстрый рост сервиса — это не только больше прибыли и довольные инвесторы, но и испытание для технарей.

В закладки

Директор по информационным технологиям Mail.ru Group Денис Аникин рассказывает, как за шесть месяцев в Ситимобил увеличили стабильность, изменив процессы разработки и автоматизации.

В 2018 году Ситимобил по количеству поездок вырос более чем в 15 раз. Когда сервис растет так быстро, вероятность сбоев в работе увеличивается. Во-первых потому, что повышается нагрузка на серверы: в нашем случае она взлетела в 100 раз. Во-вторых, становится больше функций — мы, например, стали релизиться в шесть раз чаще, — а это значит больше кода и выше вероятность ошибок.

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

Определились с понятиями

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

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

Отсюда можно вывести понятный критерий — доля успешных поездок: чем она больше, тем выше стабильность. Чем меньше поездок мы потеряли из-за внутренних технических проблем с сетевой инфраструктурой, кодом, серверами — тем лучше.

Начали все записывать

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

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

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

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

Классифицировали ошибки и нашли решения

Когда данных набралось достаточно, мы смогли классифицировать сбои и выработать алгоритмы для каждого случая.

Ошибки сервера после релиза. Отказ в обслуживании проходит через два состояния: пассивная стадия, когда мы еще не знаем про отказ (у нас простой в среднем составлял 20-25 минут), и активная, когда мы уже в курсе (около 15 минут). В сумме две стадии давали около 40 минут простоя. В течение всех этих 40 минут мы теряли поездки.

Что делать. Во-первых, нужно держать руку на пульсе. Мы сделали SMS-алерты о превышении порогового количества 500-х (internal server error) ошибок. Эти алерты помогали нам быстрее узнавать об отказе, что сократило пассивную стадию с 25 до 3 минут.

Потом мы ввели правило: разработчик выкатывает код и в течение трех минут следит за мониторингом. Если есть 500-е ошибки — значит, проблемы с его кодом, ему и разбираться. Так мы уменьшили пассивную стадию до минуты (разработчик часто замечал проблему по графикам быстрее, чем приходила SMS).

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

Во-вторых, важно быстро локализовать причину ошибки. Для этого нужно избежать параллельных релизов, которые затрудняют разбирательство. Мы установили еще одно правило: перед релизом разработчик пишет в чат, что и для чего выкатывает, а в случае аварии сигналит: «Авария, не катите!». Это позволило сократить активную стадию с 5 до 3 минут.

Потом мы автоматизировали этот процесс: после каждого релиза CI/CD-система в течение 5 минут запрещает релизить всем, кроме автора последнего релиза (чтобы у него была возможность править ошибки). Также система не дает релизить, если обнаружена авария. Автоматизация позволила сократить активную стадию до минуты. Средняя длительность аварий (активная + пассивная стадия) упала с 40 до 2 минут.

В-третьих, мы решили не допускать ошибки до пользователей. Мы завели отдельный веб-сервер с небольшой продакшн-нагрузкой для промежуточного развертывания релизов. Если в течение минуты 500-х ошибок не было, система развертывала новый код на боевых серверах. Если были, система сразу откатывала релиз. Запросы, вызвавшие 500-е ошибки на этом промежуточном сервере, дублировались на основную ферму серверов — у пользователя приложение работало без сбоев.

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

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

Что делать. Вводить обязательную проверку кода на оптимальность. Ее проводит наш спецназ — самые опытные разработчики.

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

Что делать. Настраивать SMS-алерты на все уже свершившиеся аварии — они поднимают планку качества сервиса и позволяют далее в спокойном ритме повышать надежность.

Очень важно после каждой аварий делать выводы, не скатываться в комфортную ситуацию «увидели проблему, починили и забыли».

Мина замедленного действия в коде. Ошибка, которая существует уже давно, но дала о себе знать только сейчас.

Что делать. Искать старые мины и не допускать появления новых. Поиск у нас сопряжен с постоянной оптимизацией кода.

Внешние причины. У подрядчика ломается эквайринг, геосервисы, датацентр и т. д.

Что делать. Собирать статистику по таким авариям и ждать накопления критической массы. Если накопится — менять подрядчика. Пока не накопилась, проводить post-mortem-анализ каждого падения и искать способы сделать так, чтобы все работало при недоступном внешнем сервисе.

Плохой релиз, сломанная функциональность. Единственный вид отказов, который нельзя выявить ни по каким симптомам, кроме жалоб пользователей/бизнеса.

Что делать. Всеми силами сводить этот вид отказа к категории «Ошибки сервера после релиза».

Идеально, чтобы баги в коде сохранялись в лог в виде ошибки или хотя бы оставляли следы в базе данных. По этим следам можно понимать, что случился баг, и тут же алертить. Чтобы этому поспособствовать, мы начали разбирать каждый крупный баг и находить решения, какой мониторинг/ SMS-алертинг можно сделать, чтобы этот баг проявлял себя так же, как 500-я ошибка. Для сокращения активной стадии аварии этого типа мы сделали автооткат на предыдущий релиз по некоторым видам алертинга.

Составили dos & don’ts

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

Мы завели файл с dos & don’ts, куда записываем выводы на тему разработки. Файл показываем всем новичкам. Каждый раз, когда файл дополняется, постим его в общем чате разработчиков и просим всех прочесть еще раз.

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

Сделали «Котан»

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

Этот веб-интерфейс мы назвали «Котан» — от слова «катить». В нем есть список инцидентов, справочник типов инцидентов, отчеты с выводами.

Итоги

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

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

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

Успехов вашему бизнесу и поменьше потерянных заказов, транзакций, покупок, поездок и всего, что для вас критично!

{ "author_name": "Mail.ru Group", "author_type": "editor", "tags": [], "comments": 4, "likes": 22, "favorites": 15, "is_advertisement": false, "subsite_label": "mailrugroup", "id": 68224, "is_wide": false, "is_ugc": false, "date": "Tue, 21 May 2019 11:39:43 +0300" }
{ "id": 68224, "author_id": 198687, "diff_limit": 1000, "urls": {"diff":"\/comments\/68224\/get","add":"\/comments\/68224\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/68224"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 198687, "last_count_and_date": null }
4 комментария

Популярные

По порядку

0

Интересно было видеть цифры и алгоритмы)

Ответить
0

Удивительно, но Ситимобил как новый игрок вообще красиво ворвался. Цена\качество намного выше яндекса.

Ответить

Комментарий удален

0

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

Ответить
0
{ "page_type": "article" }

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "bscsh", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223676-0", "render_to": "inpage_VI-223676-0-1104503429", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=bugf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudx", "p2": "ftjf" } } }, { "id": 16, "label": "Кнопка в шапке мобайл", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byzqf", "p2": "ftwx" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fzvc" } } }, { "id": 19, "label": "Тизер на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "p1": "cbltd", "p2": "gazs" } } } ]
Приложение-плацебо скачали
больше миллиона раз
Подписаться на push-уведомления
{ "page_type": "default" }