Привет! Меня зовут Паша Черняк, я ведущий разработчик в QIWI, и сегодня я хочу поговорить о неизбежном. О Legacy.
Начнем с вопроса: что такое Legacy-сервис? Legacy-сервис — это сервис, которого разработчик не касался уже неделю/месяц/год? Или это сервис, который был написан менее опытным программистом, например, конкретно вами, но год назад? А теперь-то вы круче и опытнее. Или все-таки, Legacy-сервис — это сервис, который вы решили никогда больше не коммитить и потихоньку готовите ему замену? В любом случае, оставлять такой сервис без присмотра и не обновлять — это бомба замедленного действия, которая может взорваться попозже.
Прежде чем переходить к тому, как мы в QIWI работаем с нашими Legacy-сервисами, я расскажу, как мы навели порядок с сервисами в Кошельке. Вот уже два года я отвечаю за его работоспособность. Если есть какая-то проблема, то всегда в первую очередь звонят мне. Мне обычно не хватает наглости в 11 часов вечера позвонить кому-то еще, поэтому приходилось садиться и разбираться во всех сервисах нашего домена.
Но я, как и любой человек, люблю спать по ночам, поэтому пытался разобраться с эксплуатацией: «Ребята, а почему вы мне звоните?». На что получил вполне лаконичный ответ вида «А кому еще?». Потому что я сервисы чиню, а еще ребята банально не знают, кому звонить.
Поэтому на одной из ретроспектив команды бекэнда Кошелька мы решили, что нужно составить табличку, на которой написан список наших сервисов, микросервисов и монолитов кошелька, и ответственных за них. Таблички это вообще полезно, в разумных пределах.
Кроме информации о том, кто за что отвечает, там были ответы на вопросы: кто владелец сервиса, кто отвечает за его развитие, за архитектуру и жизненный цикл. Люди, ответственные за этот сервис — люди, которые могут в случае чего его починить. Владелец сервиса имеет право оставить +2 в коммитах, ответственные тоже должны обязательно присутствовать на ревью, прежде чем этот сервис примет на себя новый коммит.
Время шло, начали применяться новые практики, например, миграция в Kubernetes, всякие checkstyle, spotbugs, ktlint, наличие логов в кибане, autodiscovery сервисов вместо указания напрямую адресов и прочие полезности. И везде наша таблица позволяла поддерживать актуальность наших сервисов. Для нас это некий чеклист, который говорит о том, что этот сервис вот это делать умеет, а вот этого пока еще нет Но мы шли дальше, понимая, что нам не хватает информации о наших сервисах, за которыми мы следим, где лежат исходники сервиса, где запускаются таски на сборку в TeamCity, как они деплоятся, где хранятся исходники end2end тестов, фотографии с грумингов про архитектуру, про принятые решения. В идеале хотелось, чтобы вся эта информация где-то лежала и была под рукой, когда нужно. Поэтому наша табличка стала пунктом отправления за поиском информации.
Но QIWI, хоть и сохраняет дух стартапа, является большой компанией. Нам уже 12 лет, и команды меняются: люди уходят, люди приходят, формируются новые команды. И мы обнаружили на своем домене несколько сервисов, доставшихся нам в наследство. Что-то пришло с разработчиками из других команд, что-то просто как-то опосредованно относилось к Кошельку, поэтому сервис у нас теперь на балансе. Разбираться с тем, что и как работает — зачем? Сервис же работает, и у нас есть продуктовые фичи, которые надо обязательно запилить.
Но в какой-то момент времени мы обнаруживаем, что сервис перестает выполнять свою функцию, что-то сломалось — как быть в такой ситуации? Сервис просто перестал работать. Совсем. А узнали мы об этом, во-первых, случайно, а во-вторых, через полгода. Так бывает. Единственное, что мы знали — на каких виртуалках развернут сервис, где лежат его исходники, и всё. Мы делаем git clone и погружаемся в мысли человека, который писал это несколько лет назад, но что мы видим? Никакого привычного для нас Spring Boot, хотя привыкли ко всему, у нас же full stack и все такое. Может, там есть Spring Framework? А вот и нет.
Парень, который все это писал, был суров и писал всё на чистой Java. Привычных инструментов для разработчика нет, и возникает идея — надо бы это все переписать. У нас же микросервисы есть, а из каждого тостера доносится привычное «Ребята, микросервисы — это то, что вам нужно!». Если вдруг что-то не так, вы спокойно возьмете любой язык и все будет отлично.
Штука в том, что сейчас у нас нет заказчика, который отвечает за этот сервис. Какие у него были бизнес-требования, что вообще должен делать этот сервис? А сервис плотно интегрирован в ваши бизнес-процессы.
А теперь скажите, насколько просто переписать сервис, не зная его бизнес-требований? Сервис непонятно как логируется, есть ли метрики — неизвестно. Какие они, если есть — тем более неизвестно. И при этом в сервисе огромное количество классов непонятной бизнес-логики. Что-то входит в какую-то базу данных, о которой мы тоже пока ничего не знаем.
С самого логичного — с наличия тестов. Там обычно написана хоть какая-то логика и можно сделать выводы о том, что происходит. Сейчас же модно TDD, но мы видим, что те же 5 лет назад все было практически так же, как сейчас: unit-тестов почти нет, да и не скажут они нам ровным счетом ничего. Ну кроме разве что какой-то проверки, как подписывается какой-нибудь xml с каким-нибудь кастомным сертификатом.
По коду ничего понять не удалось, и мы пошлить смотреть, чего тамна виртуалке. Открыли логи сервиса, нашли в них ошибку http-клиента, самоподписанный сертификат, который был вшит в ресурсы приложения, бессовестно протух. Мы связались с нашими аналитиками, они попросили новый сертификат, нам его выпустили и сервис снова работает. Казалось бы, что на этом все. Или нет? Все-таки сервис работает, он выполняет какую-то функцию, которая нужна нашему бизнесу. У нас есть некие стандарты разработки приложений, которые скорее всего есть и у вас. Например, не хранить логи на ноде в папке, а хранить в каком-то хранилище, типа эластика, смотреть на них в кибане. Можно вспомнить и золотые метрики. То есть нагрузка на сервис, количество запросов на сервис, жив он или нет, как у него HealthCheck проходит. По крайней мере, эти метрики помогут узнать, когда его со спокойной совестью можно вывести из эксплуатации и забыть как страшный сон.
Поэтому мы добавляем такой старый сервис в табличку, а потом идем искать из числа разработчиков добровольцев, которые займутся сервисом и приведут его в порядок: напишут хоть какую-то информацию о сервисе, добавят ссылки на дашборды в графане, на таски сборки, поймут, как разворачивать приложение, не руками же накидывать с помощью ftp файлики.
Главное — сколько вся эта полезная добровольческая активность займет времени? Один спринт для более или менее опытного разработчика, например, во время 20%-го техдолга. А сколько времени ушло на то, чтобы понять всю закоренелую логику по общению с некой госсистемой, привести ее на более новые технологии? Я за это не ручаюсь, может, месяц, а может, и два работы команды. Это я говорю по опыту интеграции в текущее время с каким-нибудь новым сервисом.
При этом выхлопа бизнес-ценности — никакого. Совсем. Взять сервис на поддержку и потратить на это немного времени — нормально. Но после наших стандартных танцев с сервисом мы добавили его в таблицу, добавили информации о нем и, возможно, когда-нибудь перепишем. Но сейчас он отвечает нашим стандартам работы сервисов.
Как итог, хотелось бы подвести к некому плану, что делать с Legacy-сервисами.
Переписывать legacy с нуля — плохая затея
Серьезно, можно даже не думать об этом. Понятно, что хотелось бы, и видятся какие-то плюсы, но обычно это не нужно никому, включая вас самих.
Справочник
Откопайте исходные коды ваших приложений, сделайте справочник, в котором будет указано, что и где лежит и как работает, туда же впишите описание проекта (условный readme.md), чтобы быстро понимать, где лежат логи и метрики. Разработчик, который будет разбираться с этим после вас, только спасибо скажет.
Понимайте домен
Если вам принадлежит какой-то домен, старайтесь держать руку на пульсе. Звучит банально, да, но не все следят за тем, чтобы сервисы были в едином ключе. А ведь работать в одном стандарте на самом деле ощутимо проще.
Начнем с вопроса: что такое Legacy-сервис? Legacy-сервис — это сервис, которого разработчик не касался уже неделю/месяц/год? Или это сервис, который был написан менее опытным программистом, например, конкретно вами, но год назад? А теперь-то вы круче и опытнее. Или все-таки, Legacy-сервис — это сервис, который вы решили никогда больше не коммитить и потихоньку готовите ему замену? В любом случае, оставлять такой сервис без присмотра и не обновлять — это бомба замедленного действия, которая может взорваться попозже.
Прежде чем переходить к тому, как мы в QIWI работаем с нашими Legacy-сервисами, я расскажу, как мы навели порядок с сервисами в Кошельке. Вот уже два года я отвечаю за его работоспособность. Если есть какая-то проблема, то всегда в первую очередь звонят мне. Мне обычно не хватает наглости в 11 часов вечера позвонить кому-то еще, поэтому приходилось садиться и разбираться во всех сервисах нашего домена.
Но я, как и любой человек, люблю спать по ночам, поэтому пытался разобраться с эксплуатацией: «Ребята, а почему вы мне звоните?». На что получил вполне лаконичный ответ вида «А кому еще?». Потому что я сервисы чиню, а еще ребята банально не знают, кому звонить.
Поэтому на одной из ретроспектив команды бекэнда Кошелька мы решили, что нужно составить табличку, на которой написан список наших сервисов, микросервисов и монолитов кошелька, и ответственных за них. Таблички это вообще полезно, в разумных пределах.
Кроме информации о том, кто за что отвечает, там были ответы на вопросы: кто владелец сервиса, кто отвечает за его развитие, за архитектуру и жизненный цикл. Люди, ответственные за этот сервис — люди, которые могут в случае чего его починить. Владелец сервиса имеет право оставить +2 в коммитах, ответственные тоже должны обязательно присутствовать на ревью, прежде чем этот сервис примет на себя новый коммит.
Время шло, начали применяться новые практики, например, миграция в Kubernetes, всякие checkstyle, spotbugs, ktlint, наличие логов в кибане, autodiscovery сервисов вместо указания напрямую адресов и прочие полезности. И везде наша таблица позволяла поддерживать актуальность наших сервисов. Для нас это некий чеклист, который говорит о том, что этот сервис вот это делать умеет, а вот этого пока еще нет Но мы шли дальше, понимая, что нам не хватает информации о наших сервисах, за которыми мы следим, где лежат исходники сервиса, где запускаются таски на сборку в TeamCity, как они деплоятся, где хранятся исходники end2end тестов, фотографии с грумингов про архитектуру, про принятые решения. В идеале хотелось, чтобы вся эта информация где-то лежала и была под рукой, когда нужно. Поэтому наша табличка стала пунктом отправления за поиском информации.
Но QIWI, хоть и сохраняет дух стартапа, является большой компанией. Нам уже 12 лет, и команды меняются: люди уходят, люди приходят, формируются новые команды. И мы обнаружили на своем домене несколько сервисов, доставшихся нам в наследство. Что-то пришло с разработчиками из других команд, что-то просто как-то опосредованно относилось к Кошельку, поэтому сервис у нас теперь на балансе. Разбираться с тем, что и как работает — зачем? Сервис же работает, и у нас есть продуктовые фичи, которые надо обязательно запилить.
Как бывает
Но в какой-то момент времени мы обнаруживаем, что сервис перестает выполнять свою функцию, что-то сломалось — как быть в такой ситуации? Сервис просто перестал работать. Совсем. А узнали мы об этом, во-первых, случайно, а во-вторых, через полгода. Так бывает. Единственное, что мы знали — на каких виртуалках развернут сервис, где лежат его исходники, и всё. Мы делаем git clone и погружаемся в мысли человека, который писал это несколько лет назад, но что мы видим? Никакого привычного для нас Spring Boot, хотя привыкли ко всему, у нас же full stack и все такое. Может, там есть Spring Framework? А вот и нет.
Парень, который все это писал, был суров и писал всё на чистой Java. Привычных инструментов для разработчика нет, и возникает идея — надо бы это все переписать. У нас же микросервисы есть, а из каждого тостера доносится привычное «Ребята, микросервисы — это то, что вам нужно!». Если вдруг что-то не так, вы спокойно возьмете любой язык и все будет отлично.
Штука в том, что сейчас у нас нет заказчика, который отвечает за этот сервис. Какие у него были бизнес-требования, что вообще должен делать этот сервис? А сервис плотно интегрирован в ваши бизнес-процессы.
А теперь скажите, насколько просто переписать сервис, не зная его бизнес-требований? Сервис непонятно как логируется, есть ли метрики — неизвестно. Какие они, если есть — тем более неизвестно. И при этом в сервисе огромное количество классов непонятной бизнес-логики. Что-то входит в какую-то базу данных, о которой мы тоже пока ничего не знаем.
С чего же начать?
С самого логичного — с наличия тестов. Там обычно написана хоть какая-то логика и можно сделать выводы о том, что происходит. Сейчас же модно TDD, но мы видим, что те же 5 лет назад все было практически так же, как сейчас: unit-тестов почти нет, да и не скажут они нам ровным счетом ничего. Ну кроме разве что какой-то проверки, как подписывается какой-нибудь xml с каким-нибудь кастомным сертификатом.
По коду ничего понять не удалось, и мы пошлить смотреть, чего тамна виртуалке. Открыли логи сервиса, нашли в них ошибку http-клиента, самоподписанный сертификат, который был вшит в ресурсы приложения, бессовестно протух. Мы связались с нашими аналитиками, они попросили новый сертификат, нам его выпустили и сервис снова работает. Казалось бы, что на этом все. Или нет? Все-таки сервис работает, он выполняет какую-то функцию, которая нужна нашему бизнесу. У нас есть некие стандарты разработки приложений, которые скорее всего есть и у вас. Например, не хранить логи на ноде в папке, а хранить в каком-то хранилище, типа эластика, смотреть на них в кибане. Можно вспомнить и золотые метрики. То есть нагрузка на сервис, количество запросов на сервис, жив он или нет, как у него HealthCheck проходит. По крайней мере, эти метрики помогут узнать, когда его со спокойной совестью можно вывести из эксплуатации и забыть как страшный сон.
Что делать
Поэтому мы добавляем такой старый сервис в табличку, а потом идем искать из числа разработчиков добровольцев, которые займутся сервисом и приведут его в порядок: напишут хоть какую-то информацию о сервисе, добавят ссылки на дашборды в графане, на таски сборки, поймут, как разворачивать приложение, не руками же накидывать с помощью ftp файлики.
Главное — сколько вся эта полезная добровольческая активность займет времени? Один спринт для более или менее опытного разработчика, например, во время 20%-го техдолга. А сколько времени ушло на то, чтобы понять всю закоренелую логику по общению с некой госсистемой, привести ее на более новые технологии? Я за это не ручаюсь, может, месяц, а может, и два работы команды. Это я говорю по опыту интеграции в текущее время с каким-нибудь новым сервисом.
При этом выхлопа бизнес-ценности — никакого. Совсем. Взять сервис на поддержку и потратить на это немного времени — нормально. Но после наших стандартных танцев с сервисом мы добавили его в таблицу, добавили информации о нем и, возможно, когда-нибудь перепишем. Но сейчас он отвечает нашим стандартам работы сервисов.
Как итог, хотелось бы подвести к некому плану, что делать с Legacy-сервисами.
Переписывать legacy с нуля — плохая затея
Серьезно, можно даже не думать об этом. Понятно, что хотелось бы, и видятся какие-то плюсы, но обычно это не нужно никому, включая вас самих.
Справочник
Откопайте исходные коды ваших приложений, сделайте справочник, в котором будет указано, что и где лежит и как работает, туда же впишите описание проекта (условный readme.md), чтобы быстро понимать, где лежат логи и метрики. Разработчик, который будет разбираться с этим после вас, только спасибо скажет.
Понимайте домен
Если вам принадлежит какой-то домен, старайтесь держать руку на пульсе. Звучит банально, да, но не все следят за тем, чтобы сервисы были в едином ключе. А ведь работать в одном стандарте на самом деле ощутимо проще.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Что вы делаете со своим legacy?
32.65% Переписываю с нуля, так правильнее16
48.98% Почти то же самое, что и вы24
12.24% У нас нет legacy, мы молодцы6
6.12% Напишу в комментариях3
Проголосовали 49 пользователей. Воздержались 27 пользователей.