Как стать автором
Обновить
907.56
OTUS
Цифровые навыки от ведущих экспертов

Go: детектор утечек горутин (Goroutine Leak Detector)

Время на прочтение3 мин
Количество просмотров7.6K
Автор оригинала: Vincent Blanchon

Перевод статьи подготовлен в преддверии старта курса "Golang Developer. Professional".

Также приглашаем всех желающих на демо-занятие "Blockchain на Go". На этом вебинаре мы создадим основанную на блокчейне упрощенную криптовалюту.


Утечку горутин можно легко обнаружить с помощью APM, который отслеживает количество работающих горутин. Вот пример из NewRelic — график, который мониторит горутины:

Источник: https://docs.newrelic.com/docs/agents/go-agent/features/go-runtime-page-troubleshoot-performance-problems
Источник: https://docs.newrelic.com/docs/agents/go-agent/features/go-runtime-page-troubleshoot-performance-problems

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

Обнаружение утечек

Команда Go в Uber, очень активная на Github, создала детектор утечек горутин (goroutine leak detector) — инструмент, который нацелен на интеграцию с модульными тестами. Этот пакет отслеживает наличие утечек горутин в текущем тестируемом фрагменте кода. Вот пример функции с утечкой горутины:

А вот тест для этой функции:

Запуск тестов обнаруживает утечку:

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

  • Вершина стека c утекшей горутиной с ее состоянием. Эта информация может помочь быстро отладить и понять, какая горутина утекает.

  • Идентификатор горутины, полезный при визуализации выполнения с помощью трейсера. Вот пример трейсов, созданных во время тестов с помощью go test ./... -trace trace.out:

Затем на основе этих трейсов вы можете детально проследить выполнение этой горутины.

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

Внутреннее устройство

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

Сначала детектор перечисляет все существующие горутины. Вот список из предыдущего примера:

Стек горутин предоставляется экспортированной функцией runtime. Stack из стандартной библиотеки Go. Следовательно, он доступен для всех, кому нужна эта информация. Однако идентификаторы горутин не экспортируются.

Затем на основе этого списка детектор может провести анализ, распарсив эти строки и удалив горутины, принадлежащие стандартной библиотеке, такие как:

  • Горутины, созданные тестовым пакетом для запуска тестов — вторая горутина (#1) из предыдущего примера.

  • Горутины, созданные средой выполнения, например те, которые слушают полученный сигнал.Чтобы узнать об этом подробнее, я предлагаю вам прочитать «Go: gsignal, Master of Signals».

  • Текущая запущенная горутина — первая горутина (#18) в предыдущем примере.

Наконец, после фильтрации, если горутин не осталось, это означает, что утечки не произошло. Однако мы видим, что у него есть некоторые ограничения:

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

  • Ложноположительный результат так же происходит, если горутина утекает в другом тесте, не покрытом детектором. Если горутина все еще будет работать при следующем запуске детектора, он ложно сообщит об утечке.

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

Стоит отметить, что этот метод также широко используется в пакете net/http для обнаружения утечек горутин. Вот пример некоторых тестов:

Здесь внутренняя функция afterTest просматривает стеки горутин чтобы найти те, которые потенциально могли протечь.


Узнать подробнее о курсе "Golang Developer. Professional".

Смотреть вебинар "Blockchain на Go".

Теги:
Хабы:
Всего голосов 11: ↑8 и ↓3+5
Комментарии0

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS