Это была хорошая охота: 13 лет CTO от прихода до ухода

в 6:59, , рубрики: 13 лет, CTO, Блог компании Туту.ру, техдиректор, управление проектами, управление разработкой
Это была хорошая охота: 13 лет CTO от прихода до ухода - 1

У нас в Туту в марте уходит CTO Вадим Мельников, который за 13 лет успел перевезти компанию из подвала с дошираком в мир высоких технологий. Не один, конечно, но Вадим был очень крутым CTO, и я хочу рассказать, как он поменял всё за это время.

В общем, никто не рассказывает про уходящих людей, ну, знаете, потому что они уже уходят. Но это, имхо, не совсем справедливо. Его история — это почти история позднего Рунета, потому что всё начиналось чуть ли не как хобби силами студентов МГУ. Дальше пришлось закупать свои сервера, ночью переезжать из Каравана в Стордату из-за конфликта хозяйствующих субъектов почти как в 90-х, учиться ставить процесс разработки от уровня «одна команда делает всё» до «это скрам-мастер, и он будет жить с нами», делать невероятно прогрессивный монолит с библиотеками с фасадами, переходить на архитектуру с шиной и потом ещё раз переходить на микросервисы в контейнерах, строить своё персональное облако на своём железе, с удивлением узнавать, что ИБ всё-таки нужна (иначе ляжем и быстро) и много других вещей.

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

30 дней на то, чтобы не упасть

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

Опять же, напомню, билеты тогда были только бумажные, и речь шла не про их продажу, а про заработок с рекламы. Вот рассказ про то, как люди ездили на вокзалы, чтобы сфотографировать табло и специальные листальные механические аппараты с расписаниями. Это всё переносилось в Рунет. И вот Вадим пришёл делать новый продукт. И почти с порога он встретил Костю Куликова, спокойного и уравновешенного человека в состоянии, близком к охреневанию. Что вообще-то для него не очень характерно.

Дело вот в чём. Основной доход давала реклама, и в момент, когда этот доход был выше всего, сайт обычно падал. До следующего запланированного падения оставалось ровно 30 дней. Вадим пришёл 30 марта, а 30 апреля утром начинался шквал людей. Опять же, ситуация объясняется менталитетом. Если немцы покупают билеты сильно заранее, например, за полгода, то у нас в России прямо перед майскими праздниками люди начинали лихорадочно запрашивать расписания электричек и поездов.

Предыдущие 3 года tutu.ru регулярно падал именно в этот день. И это стало традицией.

Это была хорошая охота: 13 лет CTO от прихода до ухода - 2
Вот так это выглядело в 2003-м году

Итак, у Вадима на старте:

  • Компания из 7 человек в полуподвальном помещении, из которых технарей двое основателей. И они прямо сейчас уезжают через пол-планеты. Как позже Вадим узнал, это может в любой момент относиться к любому сотруднику компании, потому что мы тут все про путешествия. То есть ему одному надо как-то всё подготовить.
  • Два разработчика-аутсорсера.
  • Сайт на шаред-хостинге с PHP-спагетти кодовой базой, выдерживающий среднюю нагрузку в 25 тысяч хостов в сутки.
  • База данных в виде txt-файлов.
  • Пачка доширака в виде первого квестового предмета для инвентаря.

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

  • Распределил нагрузку между беком и фронтом. Это довольно легко сказать в одном предложении, но вообще-то довольно сложно сделать. Выделил фронт-прокси (привет Nginx), разделил бек на несколько нод.
  • Выделил СУБД (те самые текстовые файлики, которые всё же как-то оркестрировались) в ещё один инстанс.
  • Выделил отдельно рекламную крутилку (она иногда баговала и падала, чем роняла заодно всё остальное — теперь она падала в гордом одиночестве).
  • И купил два первых сервера компании:

Да это я, сервер

30 апреля пришло 120 тысяч человек, и всё выдержало. Не отвалилась даже реклама.

1 мая Вадим был занят. Сильно.

2 мая он начал решать настоящие задачи CTO.

Настоящие задачи CTO

На 2009 год ИТ-ландшафт выглядел так:

  • Расписание электричек крутилось на самопальной СУБД из текстовых файлов под управлением набора достаточно разрозненных PHP-скриптов.
  • Железнодорожное расписание (поездов дальнего следования) крутилось на таком же движке, только форке.
  • Авиацию делали отдельно на новом движке. Особенно интересно была реализована продажа билета: тогда не было никаких whitelabel-виджетов или API, зато была страница Амадеуса, где можно было купить билет. Эта страница хакалась во все возможные дыры, получала новый CSS и вставлялась в мастер покупки, в результате чего, как сейчас говорят, пользователь получал бесшовный опыт интеграции. Короче, это было похоже на пересбор движка через выхлопную трубу.

Нужно было продумать правильную архитектуру, задуматься про развитие и готовиться к тому, что нагрузки росли постоянно. Забегая вперёд скажу, что миллион пользователей (хостов) в день в пике был не за горами, а потом он стал нормой.

Вадим начал набирать команду своими силами (потому что HR и рекрутёров тогда тоже не было). Появился первый бек в штате, потом верстальщик и ещё бек.

В 2010 году случилась полная переделка бека и фронта. Отказались от *.txt-driven СУБД, перешли на MySQL. Ввели кэширование всего. Вместо спагетти-файлов PHP сделали фреймворк: монолит (тогда ничего другого и не было), но монолит ультрасовременный по тем временам, с ортогональным набором библиотек, взаимодействующими через фасады. Каждая библиотека отвечала за свою предметную область и выставляла наружу интерфейс (фасад). Это такое протоAPI из эпохи монолитов. Например, с MySQL можно было бы перейти на PostgreSQL почти безболезненно. Теоретически.

То есть сразу фреймворк строили, используя паттерны проектирования.

Одновременно с переездом на новый фреймворк решали задачу полного обновления дизайна tutu.ru. Тестовые среды, разумеется были, но проверить реальную нагрузку на них не было никакой возможности. Первый раз на новый движок переключились в 23:00 субботы, чтобы увидеть, как она умирает по перегрузке сервера через 4 минуты 49 секунд. Переключились обратно и стали думать, и начали анализировать логи, как все умирало. Каждый новый запуск давал нам больше информации, что идет не так. На третий раз мы продержались более часа. В какой-то момент даже перефразировали старую шутку: «Логирование показало, что пациент умер в результате логирования». Масштабные тестовые среды приехали много позже, здесь точно так же переключались по ночам несколько раз. В общей сложности около месяца ушло на запуск, грепание логов и поиск оптимизаций. В конце июля смогли запустить и оставить работать уже надолго.

В 2011 году была команда из 5 ИТ-специалистов. Стало понятно, что на этом история не закончится, и надо больше людей. Когда у вас 5 человек, управлять ими можно вручную понятийно. Когда становится уже 8-9 — нужно использовать какие-то механики управления. Собственно, так в компании появился Agile. Понятно, что первый год внедрения аджайла аджайлом там и не пахло. Поначалу это было просто «лежим в сторону скрама». Но как-то работу это упорядочивало.

Процесс тестирования на релизе стал реально мешать жить.

В самом фреймворке уже использовались юнит-тесты, покрытие было разное, но было. Понадобилось добавлять приёмочные, интеграционные тесты. Появился Селениум (сначала IE, потом вебдрайвер). Покрытие стало расти, а вместе с ним и качество выкладок.

Параллельно работали с инструментами для выкладывания обновлений. Поскольку сайт нагруженный – надо было аккуратно включать-выключать отдельные беки, обновлять базы и так далее. Пришлось курить бамбук. В конечном итоге монолит стал выкладываться через Atlassian Bamboo. В этот же момент для задач появилась Jira, а для базы знаний Конфла. До этого исторического периода был Subversion, переехали на Git.

В конце 2011 года стало понятно, что всё не может жить в одной базе данных. Точнее, как. Инстансов MySQL было много, это были Master-Slave репликации. Но логически это была одна база, и ей становилось всё тяжелее управлять. Высоконагруженная маленькая табличка жила рядом с большой и не такой нагруженной. Когда что-то падало — надо было восстановить не кусок базы, а ждать полного накатывания бекапа. Ещё 2 года ушло на то, чтобы постепенно растаскать базу по маленьким кусочкам, сделать правильную балансировку и правильно разделить всё это в коде. Заказы стали жить отдельно, расписания отдельно, ЖД и авиа не делили таблицы, отдельно учитывались пользователи, отдельно системные вещи. На выходе у нас значимых логических баз около 30, а инстансов за 200. Процесс балансировки там впечатляющий, и, надеюсь, когда-нибудь инженеры из славного рода девопсов напишут про это.

Тогда же запустили отели и туры. Параллельно шла история переездов из ЦОДа в ЦОД и появление геонезависимого резервирования, вот про это пост Вадима. Короткая выжимка такая: от шаред-хостинга ушли в 2009, дальше расширялись на своих железных серверах, которые ставили в разные ЦОДы. На момент потери Каравана серверов было 15 штук. Как раз тогда только прокинули прямой линк от их ЦОДа до Стордаты, и внезапно он очень пригодился. Правда, только один раз.

Если раньше офис покупал себе мышки-клавиатуры-системники сам, то теперь понадобилась служба админов. Что ещё важнее, внешние системы надо было переводить внутрь — например тот же почтовый сервер.

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

В этот же момент стало понятно, что если продуктовые команды будут заниматься ещё и инфраструктурой, фокус у них размоется. Появилась инфраструктурная команда, которая позже стала командой ИТ-платформы. Это девопсы и разработчики инструментов для разработчиков. «Котики» (так эта команда сама себя решила называть) разрабатывали системные библиотеки, инструменты выкладки, обвешивали всё мониторингом.

В конце 2014 года стало понятно, что архитектура поворачивает в сторону сервис-ориентированной. Тогда это были не микросервисы, а шины и брокеры сообщений. Поспособствовало этому развитие сетевых технологий. Почему раньше был монолит? Потому что сообщение между разными частями системы или между разными методами ходили через оперативную память напрямую или через стек вызовов функций — а это быстро. Сервис-ориентированная архитектура больше про сетевые запросы. В 2010-м году даже гигабитную сетку иметь было дорого. У нас была такая, но вот 10 Гб — уже нет. А вот в 2014 году 1 Гб был везде, местами потепления до 10.

Офисные админы со временем обзавелись сервисдеском, начали отслеживать SLA по закрытию задач. Появилось окно поддержки, которое работает через плагин Service Desk в Джире, которое помогало в понятной форме поставить формальный тикет. То есть вы туда писали, что нужно, а дальше уже он адресовался от АХО до админов и котов и снабжался формальными признаками.

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

Запустили расписания автобусов — вся вертикаль была разработана на SOA, на ней смотрели, взлетит или нет. Тогда же началось разбирание монолита, опять же, вот эпический пост про его обращение с техдолгом и историю этого небыстрого процесса. Переход шёл тяжело. Сервисная (а потом и микросервисная) модель требует другого проектирования, а разработчики не были готовы к такому. Брали монолит, просто в лоб переписывали старые вызовы в сетевые, дальше всё тормозит. Некоторое время переучивались мыслить порталами.

Очень усложнилась отладка. Если с одного физического сервера можно было руками собрать лог, то тут нужны были уже нормальные мониторинги. Одно только разбирательство с происходящим внутри RabbitMQ-кластера могло расшатать психику самым спокойным из админов. Сначала начали внедрять Scribe (это фейсбуковская штуковина), научили готовить, поженили с нашим фреймоврком. Это каскадный сбор логов, не совсем идеальный, но работающий. Он иногда что-то терял, но некритично. В 2016, кстати, поменяли его на Эластик + Кибану. Мониторинги тоже были сначала свои доморощенные, потом Графана с набором скриптов, сейчас Прометей с Графаной.

ИБ исторически развивалась по остаточному принципу. Первые столкновение с суровой реальностью случилось в 2015, когда нас первый раз серьёзно задидосили. Тогда отработали самостоятельно вместе с хостинг-провайдером, но самостоятельно такое делать очень не понравилось. Когда нас пытались положить второй раз, уже были почти готовы переключаться на QRator. Третий раз отработали уже они, и про DDoS мы на некоторое время забыли. А атаки случались постоянно, что мы узнавали, к счастью, из статистики Куратора, а не из мониторинга серверов. Дальше стало понятно, что ИБ всё же нужно серьёзно заниматься (сюприз!) и начали что-то делать. Что-то — это создали отдел и стали искать у себя дыры. Постоянно заказывали и заказываем пентесты и исследования.

В 2016 году стали появляться сложности с железной инфраструктурой. Хотелось запускать много продуктов, а для этого нужно было быстро закупать железо. Быстро закупать железо — это фантастика, поэтому решили воспользоваться сторонними IaaS. Добавили гибкое озеро ресурсов в паре ЦОДов.

Тогда же решили двигаться в сторону микросервисов. Сначала делали по-старинке без оркестрации (просто на docker-контейнерах), потом собрались и быстро перешли в 2017 году на PaaS на k8s с Openshift. Микросервисы, Go, все дела. Интересно, что команде PaaS тогда Вадим задачу поставил так: «Парни, вы пока никому не нужны, все привыкли работать как работали, сделайте так, чтобы они захотели к вам и по-новому. Никого заставлять не будем». В итоге за год продукт стал настолько хорошим, что туда переехали почти все.

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

В 2017 году появились BI-решения для аналитики, начали внедрять работу с большими данными, трафика и событий хватало. Хадуп не стали внедрять, собирали всё сначала в Эластик, потом (позже) стали в Кликхаусе. Как раз в 17 году подключили Метабейз для работы со стандартными отчётами.

Системно на уровне процессов end-to-end ИБ появилось в компании только в 19 году. Напомню, до этого была SecaaS, нанимали ребят с моделью угроз, пентестами, проходили PCI DSS-сертифкацию для платёжного шлюза. Потом внутренний отдел развернул инструменты поиска аномалий пользователей и юзеров, мониторинг действий админов (если что-то странное происходило под привилегированной учёткой, то звонили спросить, что происходит). Поймали первый случай, когда админ ничего не делал, а в учётке творились массовые страшные вещи. К счастью, оказалось, что это одичал один из роботов. Робот отделался лёгким испугом и выговором, а вот архитектурно так делать было нельзя. Появились регламенты, а в потом позже и DevSecOps – когда ИБ проверяет всё ещё на этапе разработки, чтобы изначально было безопасно. К слову, на первых таких релизах TTM увеличился, потому что оказалось, что можно релизить с десятками критикалов, и их надо срочно закрывать.

В конце 2019-го начали делать собственное приватное облако на своём железе: получалось дешевле, чем арендовать чей-то IaaS. Стояли уже в 5 ЦОДах, доделали балансировку и передвинули сервисы так, чтобы можно было выжить даже при отказе 2 из 5 узлов. Последнее крупное падение было в 2020 после речи президента, кстати, но там реально эпическая комбинаций совпадений, вот этот пост с деталями.

Что важного сделал Вадим

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

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

В-третьих, мы почти никогда не упирались в инфраструктуру. Всё, что было нужно по ресурсам железа, всегда было — и при этом в разумных бюджетах.

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

А где плохо?

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

Самая главная проблема — резкое замедление разработки на стыках команд. Раньше каждая вертикаль (авиация, железнодорожные билеты, автобусы) действовала самостоятельно. Теперь надо делать единый сервис. Это дало большое количество взаимосвязей между продуктами и командами. Точнее, сначала предполагалось, что стыки будут только в ядре типа общих платёжных шлюзов, общих авторизаций и так далее, и там архитектура с ИТ-платформой показала себя очень хорошо. Но стратегически мы не совсем точно оценили, насколько сейчас вертикали сливаются для новых сервисов. Новым продуктам уже пофиг, чем пользователь доберётся до нужной точки, они хотят одинаково легко дёргать и автобусы, и поезда, и самолёты. Одна только единая выдача расписания потребовала, чтобы дизайнеры морщили лоб и договаривались с продуктами больше года. А сейчас больше половины новых фич — кросспродуктовые.

Мы объективно ещё не совсем научились управлять процессами разработки в ситуации, когда одна продуктовая команда очень зависит от двух других продуктовых, и это надо менять. Мы объективно пока путаемся во внутренних ресурсах: появились люди, которые не знают про каталог API и инструменты работы с ними, часто пишутся велосипеды вместо переиспользования кода, многие сервисы непонятно как поддерживаются (и поддерживаются ли вообще). Там нужна генеральная уборка с выкидыванием того, что лучше пристрелить и появлением понятных процессов разработки.

Нам сейчас придётся заново переизобретать обучение. Какие-то костыли мы уже вбили, но нужна целостная модель.

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

Вадим оставил в наследство стратегию развития. Там 8 базовых целей: ускорение через минимизацию типовых операций, надёжность и доступность (научиться считать в деньгах разные виды сбоев, а потом минимизировать риски, используя финансовую стратегию тоже), стандартизировать основные инженерные процессы (это как раз про общие API, например), улучшить качество данных (больше мониторинга!) и доступ к этим данным, развивать дальше ИБ и развивать команду.

Ну и, конечно, мы очень замедлились. Вадим уходит, потому что ему гораздо комфортнее работать в проектах, где есть чёткое понимание будущей стратегии на несколько лет вперёд. По сути, CTO отчасти и формирует такую стратегию, но теперь настала та прекрасная стадия, где это нужно делать вместе с глубоким пониманием рынка и будущего. У нас точного видения нет, соответственно, в текущей парадигме готовиться надо ко всему и сразу, что утяжеляет архитектуру и создаёт много переобуваний на ходу. Техническая стратегия может снизить издержки на этих переобуваниях. Конечно, Вадим остаётся в совете директоров, но вот прямо вонзаться в рабочие процессы перестал. А поле для работы осталось большое. Мы открыты для нового чуть больше, чем средняя компания рынка. Мы №1 в тревеле по трафику в России, есть хайлоад, много мощностей, много работающих вещей, классная команда, сильные админы, ИТ-дривен компания с одной стороны. С другой — медленное принятие решений (не всегда справляется система целеполагания, сейчас только вводим это, но ещё минимум год будут подтормаживания), рассинхрон в разных продуктах и направлениях, часто не самые сильные в технической части продакты. Мы сейчас собираемся делать маркет для путешествий, и это могла бы быть крутая строчка в списках достижений для любого CTO — но его ещё никто не делал, и это путь, предположительно, довольно мучительных попыток и ошибок.

Скорее всего, нужно переосмысливать и его роль как таковую, и менять её на несколько — отдельно нужен директор, ответственный за инфраструктуру и развитие, отдельный CDO, отдельно операционщик. Сейчас роль Вадима временно подхватил Дима Хрупов khrupov, который вернулся в операционную деятельность, но, естественно, мы ищем и CTO тоже, причём либо «целого», либо несколько разных человек. И да, Вадим вот: Molodoi.

Автор: Сергей Абдульманов

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js