14 лет пишу код, 10 - в прод. Руковожу командой инженеров в Т-Технологиях.
📌 Backend, Data, System Design
📌 Concurrency, Performance, Algorithms
📌 Infrastructure, Reliability
📌 Карьера, Менеджмент
Для связи: @ea_kozlov
Post #471
432
Результаты опроса меня впечатлили. Большинству интересны истории из работы. Поехали, начнем с истории из моего джунства. Разминка и затравка.
Джун SRE или как я чинил прод на Go с опытом работы меньше месяца и не зная Go
На дворе 2016й. Я впервые задумываюсь о поиске работы в своем родном городе Брянске. По итогу поисков я устроился в веб студию разрабатывающую фичи на заказ. Я устроился бэкэнд разработчиком поддерживать и писать проекты на Ruby on Rails.
Одним из проектов которым я занимался было приложение для пополнения карт Тройка в Москве. Он был разделен на 2 части:
- API для мобильного приложения (на RoR)
- API на Golang для работы непосредственно с эквайринговыми провайдерами.
В целом я быстро погрузился в первую часть системы. Во вторую погружение не требовалось. Она просто работала. До поры до времени.
Первые звоночки
Однажды я пришел на работу и обнаружил что сервис на Go упал ночью. В логах я не обнаружил ничего интересного кроме:
Уже не помню было ли на сервере настроен systemd который перезапускал упавший процесс, но в любом случае выглядело это эпично.
Из обсуждения с тимлидом я сделал вывод, что на поверхности решения проблемы не видно и нужно разбираться. А у меня какое то время не было новых продуктовых задач на проектах. И уже не помню: он предложил мне или я вызвался - в общем задача разобраться с триггером, причиной и устранением дефекта досталась мне.
Сбор фактуры. Установление причины.
Первое с чего я начал - сбор всей доступной телеметрии. Я изучил причины почему вообще ошибка называется too many open files. Курс по линуксу в универе был свеж в моей голове и я быстро сориентировался. Дело врядли в файловой системе, а скорее всего в том что в линуксе "всё есть файл" и вот с какими то конкретными файлами у моего процесса проблемы. Так как сервис был развернут просто на голой виртуальной машине и у меня был доступ по ssh я имел полную свободу действий.
По итогу вот такая команда выдала мне то что я искал:
Показатель монотонно растет, при достижении значения 1000 процесс падает с той самой ошибкой.
Погружение в код. Поиск триггера
Найдя причину мне стало немного легче. Но задача только набирала обороты. В моем распоряжении критичный по функциональности сервис на языке Go, языке с которым я не работал никогда. И надо в нем искать багулю (а мб бага вообще не в нем).
Изучив всю кодовую базу я обнаружил что единственная вещь которая может повлиять на найденную ранее метрику - работа http client. В Go это обычно выглядит так:
И собственно все стало на свои места. Погрузившись в доку гошки я черным по белому увидел что
влияет на метрику найденную на шаге №1.
Осталось дело за малым, найти кейс в коде когда resp.Body.Close() не выполняется. 30 минут вдумчивого и внимательного чтения и я вижу вот такой код:
Я понял, вот оно. Мы не закрываем соединение если апи поставщика вернула статусы выше 400х. Почему так было сделано я не стал разбираться. Я понял что это явно неправильно поведение. Будучи на эмоциональном подъёме несу МР с фиксом тимлиду, получаю LGTM и мы вместе его катим. Фикс был примитивный:
Это был выстрел в яблочко, после наката новой версии значение найденной мной метрики держалось на одном уровне. Я до сих помню эти ощущения, чувство победы над вещью которая пару дней назад казалось нереальной.
Выводы
Чему меня научила эта история? Учеба в универе и некоторые предметы точно не лишние в работе😊
А если серьезно - не бояться залезать в сложные и неочевидные проблемы. Да у тебя может не быть на бумаге нужного опыта, да и вообще ты джун на испыталке, ну и что? Траблшутинг это вещь которой нельзя научиться в теории, ей учишься исключительно на практике. И с ростом практики начинаешь понимать почему методологии дебага и траблшутинга из умных книг и статей именно такие.
Вот такая история, делитесь в комментариях, помните ли вы свой первый баг, как его чинили?) Ну и делитесь фидбэком, как вам такой формат😊
Джун SRE или как я чинил прод на Go с опытом работы меньше месяца и не зная Go
На дворе 2016й. Я впервые задумываюсь о поиске работы в своем родном городе Брянске. По итогу поисков я устроился в веб студию разрабатывающую фичи на заказ. Я устроился бэкэнд разработчиком поддерживать и писать проекты на Ruby on Rails.
Одним из проектов которым я занимался было приложение для пополнения карт Тройка в Москве. Он был разделен на 2 части:
- API для мобильного приложения (на RoR)
- API на Golang для работы непосредственно с эквайринговыми провайдерами.
В целом я быстро погрузился в первую часть системы. Во вторую погружение не требовалось. Она просто работала. До поры до времени.
Первые звоночки
Однажды я пришел на работу и обнаружил что сервис на Go упал ночью. В логах я не обнаружил ничего интересного кроме:
too many open files
Уже не помню было ли на сервере настроен systemd который перезапускал упавший процесс, но в любом случае выглядело это эпично.
Из обсуждения с тимлидом я сделал вывод, что на поверхности решения проблемы не видно и нужно разбираться. А у меня какое то время не было новых продуктовых задач на проектах. И уже не помню: он предложил мне или я вызвался - в общем задача разобраться с триггером, причиной и устранением дефекта досталась мне.
Сбор фактуры. Установление причины.
Первое с чего я начал - сбор всей доступной телеметрии. Я изучил причины почему вообще ошибка называется too many open files. Курс по линуксу в универе был свеж в моей голове и я быстро сориентировался. Дело врядли в файловой системе, а скорее всего в том что в линуксе "всё есть файл" и вот с какими то конкретными файлами у моего процесса проблемы. Так как сервис был развернут просто на голой виртуальной машине и у меня был доступ по ssh я имел полную свободу действий.
По итогу вот такая команда выдала мне то что я искал:
lsof -p <PID> | wc -l
Показатель монотонно растет, при достижении значения 1000 процесс падает с той самой ошибкой.
Погружение в код. Поиск триггера
Найдя причину мне стало немного легче. Но задача только набирала обороты. В моем распоряжении критичный по функциональности сервис на языке Go, языке с которым я не работал никогда. И надо в нем искать багулю (а мб бага вообще не в нем).
Изучив всю кодовую базу я обнаружил что единственная вещь которая может повлиять на найденную ранее метрику - работа http client. В Go это обычно выглядит так:
resp, err := http.Get("https://gobyexample.com")
if err != nil {
return err
}
defer resp.Body.Close()
// бизнес логикаИ собственно все стало на свои места. Погрузившись в доку гошки я черным по белому увидел что
resp.Body.Close()
влияет на метрику найденную на шаге №1.
Осталось дело за малым, найти кейс в коде когда resp.Body.Close() не выполняется. 30 минут вдумчивого и внимательного чтения и я вижу вот такой код:
// http запрос
if resp.Status >= 400 || err != nil {
return "что то там"
}
defer resp.Body.Close()
// бизнес логика
Я понял, вот оно. Мы не закрываем соединение если апи поставщика вернула статусы выше 400х. Почему так было сделано я не стал разбираться. Я понял что это явно неправильно поведение. Будучи на эмоциональном подъёме несу МР с фиксом тимлиду, получаю LGTM и мы вместе его катим. Фикс был примитивный:
// http запрос
if err != nil {
return err
}
defer resp.Body.Close()
if resp.Status >= 400 {
return "что-то там"
}
Это был выстрел в яблочко, после наката новой версии значение найденной мной метрики держалось на одном уровне. Я до сих помню эти ощущения, чувство победы над вещью которая пару дней назад казалось нереальной.
Выводы
Чему меня научила эта история? Учеба в универе и некоторые предметы точно не лишние в работе😊
А если серьезно - не бояться залезать в сложные и неочевидные проблемы. Да у тебя может не быть на бумаге нужного опыта, да и вообще ты джун на испыталке, ну и что? Траблшутинг это вещь которой нельзя научиться в теории, ей учишься исключительно на практике. И с ростом практики начинаешь понимать почему методологии дебага и траблшутинга из умных книг и статей именно такие.
Вот такая история, делитесь в комментариях, помните ли вы свой первый баг, как его чинили?) Ну и делитесь фидбэком, как вам такой формат😊
- 🔥 16
- 👍 5
- ❤ 4
