Анализируйте показатели Go

Материал из Документация Ключ-АСТРОМ

Ключ-Астром ЕдиныйАгент отслеживает множество показателей, связанных с Go.

Вкладки «Метрики Go» и «Метрики Go HTTP» на странице обзора процесса содержат наиболее важные метрики Go и HTTP. Вкладки «Управляемая память Go», «Сведения о куче» и «Планирование», доступные через вкладку «Дополнительные сведения», дают еще более ценную информацию о производительности вашего приложения на основе Go.

Ключевые метрики

На вкладке «Метрики Go» представлены следующие важные метрики Golang:

  • Приостановка: процентная доля сборщика мусора Go по сравнению с общим временем ЦП приложения.
  • Куча времени выполнения: объем памяти, используемый или зафиксированный в куче Go, а также время сборки мусора Go.
  • Goroutines: количество Goroutines, созданных приложением и инфраструктурой времени выполнения Go.

Метрики HTTP

На вкладке «HTTP-метрики Go» вы можете изучить следующие HTTP-метрики:

  • Всего запросов: количество всех запросов, представляющих общий поток трафика.
  • Количество ответов HTTP 5xx: количество ответов, которые указывают на повторяющиеся сбои приложений или проблемы с ответами приложений.
  • Количество неверных HTTP-шлюзов: количество ответов, указывающих на недопустимые ответы службы, созданные приложением.
  • Задержка ответа: среднее время ответа от приложения к клиентам.

Перейти к управляемой памяти

Вкладка управляемая память Go разбивает показатели памяти на различные категории:

  • Куча: объем памяти, используемый или зафиксированный в куче времени выполнения Go.
  • OffHeap: объем памяти, используемой или зафиксированной во внутренних структурах среды выполнения Go, которые не выделяются из памяти кучи. Структуры данных, используемые в реализации Go Heap, являются примером памяти OffHeap.
  • Итого: сумма памяти кучи, OffHeap и стека.
  • Стек: объем памяти, используемой или выделенной для динамических стеков Go. Стеки Go используются для выполнения Goroutines и динамически растут.

Детали кучи

Вкладка «Детали кучи» позволяет глубже изучить анатомию кучи Go.

  • Количество объектов Go, выделенных кучей: количество объектов Go, размещенных в куче Go.
  • Размер кучи в режиме ожидания: объем памяти, не назначенный куче или стеку. Простаивающая память может быть возвращена операционной системе или сохранена средой выполнения Go для последующего переназначения в кучу или стек.
  • Активный размер кучи: объем памяти, который сборщик мусора Go считает активной. Этот показатель накапливает память, оставшуюся после последнего запуска сборщика мусора и выделенную с тех пор.
  • Счетчик вызовов сборщика мусора: количество запусков сборщика мусора Go.

Планирование

О планировании Goroutines

Базовое понимание принципов внутреннего планирования поможет вам прочитать показатели планирования и обнаружить потенциальные аномалии.

Реализация планирования Goroutine имеет дело с тремя центральными типами объектов: M (Machine), P (Processor) и G (Goroutine). Вы можете найти несколько экземпляров этих типов объектов в исходном коде среды выполнения Go. Для простоты Ключ-Астром использует следующие альтернативные термины:

Срок выполнения Go Срок действия Ключ-Астром
M (Machine) Worker thread
P (Processor) Scheduling context
G (Goroutine) Goroutine

Go выполняет Goroutines в контексте рабочих потоков, полученных из пула собственных потоков операционной системы. Goroutine может быть назначен другому рабочему потоку в любое время, если только среда выполнения. LockOSThread не используется для обеспечения привязки рабочего потока.

Несколько Goroutines обычно назначаются одному рабочему потоку. Контекст планирования отвечает за совместное планирование Goroutines. Компилятор Go добавляет код к каждому прологу функции Go, который проверяет, использовала ли выполняемая в данный момент Goroutine свой временной отрезок в 10 миллисекунд. Фактический механизм умело использует защиту стека для принудительного изменения расписания. Если временной интервал превышен, контекст планирования устанавливает следующую Goroutine для выполнения. До Go 1.14 планирование было полностью совместным, что приводило к проблеме с Goroutines, которые не вызывали функции Go и, следовательно, не переносились. Go 1.14 представил механизм, позволяющий упреждающее планирование Goroutines для обработки этого особого случая.

Каждый набор Goroutines выполняется рабочим потоком. Выполнение контролируется контекстом планирования. Когда Goroutine записывает большой кусок данных на диск или блокирует ожидание входящего соединения, Goroutine блокируется в системном вызове, и никакие другие Goroutine не планируются. В такой ситуации контекст планирования с другими Goroutines назначается другому рабочему потоку, либо припаркованному, либо вновь созданному. Эти Goroutines не блокируются системным вызовом и могут продолжать выполнение. Следовательно, общее количество рабочих потоков больше, чем количество объектов контекста планирования. После того, как блокирующий вызов возвращается, Goroutine снова назначается контексту планирования. Если назначение не удается, Goroutine отправляется в глобальную очередь выполнения Goroutine. Тот же принцип применяется к вызовам cgo (перейти на язык C).

Количество контекстов планирования - это единственный параметр, который вы можете настроить в алгоритме планирования Go. Вы не можете контролировать количество рабочих потоков. Вот почему запись большого объема данных на диск или ожидание входящих соединений не будет блокировать другие Goroutines, которые изначально назначены тому же рабочему потоку. Эти Goroutines продолжают выполнение своих вновь назначенных рабочих потоков.

Вкладка «Планирование» предоставляет уникальные сведения о планировании Goroutine.

  • Go runtime system call count: количество системных вызовов, выполненных средой выполнения Go. В это число не входят системные вызовы, выполняемые кодом пользователя.
  • Go to C language (cgo) call count: количество вызовов cgo.
  • Parked worker thread count: количество рабочих потоков, припаркованных средой выполнения Go. Припаркованный рабочий поток не использует циклы ЦП до тех пор, пока среда выполнения Go не отключит поток.
  • Out-of-work worker thread count: количество рабочих потоков, в связанном контексте планирования которых больше нет Goroutines для выполнения. Когда это происходит, рабочий поток пытается украсть Goroutines из другого контекста планирования или глобальной очереди выполнения. Если кража не удалась, рабочий поток через какое-то время паркуется. Этот же механизм применяется к сценарию с высокой рабочей нагрузкой. Когда существует неактивный контекст планирования, среда выполнения Go снимает парковку с припаркованного рабочего потока и связывает его с неактивным контекстом планирования. Незапаркованный рабочий поток теперь находится в состоянии «не работает» и начинает кражу Goroutine.
  • Worker thread count: количество потоков операционной системы, созданных для выполнения Goroutines. Go не завершает рабочие потоки; он сохраняет их в припаркованном состоянии для повторного использования в будущем.
  • Global Goroutine run queue size: количество Goroutine в глобальной очереди выполнения. Goroutines помещаются в глобальную очередь выполнения, если рабочий поток, используемый для выполнения системного вызова блокировки, не может получить контекст планирования. Контексты планирования периодически получают Goroutines из глобальной очереди выполнения.
  • Idle scheduling context count: количество контекстов планирования, в которых больше нет Goroutines для выполнения и для которых получение Goroutines из глобальной очереди выполнения или других контекстов планирования не удалось.