Go-фича: Метрики горутин
Часть серии Принято! В ней простыми словами объясняются новые фичи Go.
Подробные метрики горутин от рантайма.
Версия 1.26 • Станд. библиотека • Полезно
Что
Новые метрики в пакете runtime/metrics позволяют лучше понять, как работают горутины:
- Общее количество горутин с начала работы программы.
- Количество горутин в каждом состоянии.
- Количество активных потоков.
Зачем
Пакет runtime/metrics уже предоставляет много информации о работе программы, но в нем не хватало метрик по состояниям горутин и количеству потоков.
Метрики по состояниям горутин помогают находить типичные проблемы в продакшене. Например, если растет число горутин в состоянии waiting, это может указывать на проблемы с блокировками. Много горутин в состоянии not-in-go — значит, они застряли в системных вызовах или cgo. Если увеличивается очередь runnable — CPU не справляются с нагрузкой.
Системы мониторинга могут отслеживать эти показатели, чтобы замечать ухудшения и отправлять оповещения, если поведение горутин меняется. Разработчики могут использовать метрики, чтобы раньше обнаруживать проблемы, не прибегая к полным трассировкам.
Как
Добавить следующие метрики в пакет runtime/metrics:
/sched/goroutines-created:goroutines
Общее количество горутин, запущенных
с момент старта приложения (накопительный итог).
/sched/goroutines/not-in-go:goroutines
Примерное количество горутин, которые
«ушли» в системный или cgo-вызов.
/sched/goroutines/runnable:goroutines
Примерное количество горутин, которые готовы
к выполнению, но пока не выполняются.
/sched/goroutines/running:goroutines
Примерное количество выполняющихся горутин.
Всегда меньше или равно /sched/gomaxprocs:threads.
/sched/goroutines/waiting:goroutines
Примерное количество горутин, ожидающих
на ресурсе (I/O или примитивы синхронизации).
/sched/threads/total:threads
Текущее количество активных потоков,
которыми управляет планировщик Go.
Сумма значений показателей по каждому состоянию не обязательно равна общему количеству активных горутин (метрика /sched/goroutines:goroutines, доступна в Go 1.16+).
Все метрики используют счетчики типа uint64.
Пример
Запускаем несколько горутин и выводим метрики через 100 мс работы:
func main() {
go work() // omitted for brevity
time.Sleep(100 * time.Millisecond)
fmt.Println("Goroutine metrics:")
printMetric("/sched/goroutines-created:goroutines", "Created")
printMetric("/sched/goroutines:goroutines", "Live")
printMetric("/sched/goroutines/not-in-go:goroutines", "Syscall/CGO")
printMetric("/sched/goroutines/runnable:goroutines", "Runnable")
printMetric("/sched/goroutines/running:goroutines", "Running")
printMetric("/sched/goroutines/waiting:goroutines", "Waiting")
fmt.Println("Thread metrics:")
printMetric("/sched/gomaxprocs:threads", "Max")
printMetric("/sched/threads/total:threads", "Live")
}
func printMetric(name string, descr string) {
sample := []metrics.Sample{{Name: name}}
metrics.Read(sample)
// Предполагаем, что значение типа uint64; так делать в продакшене не стоит.
// Лучше действовать в соответствии с sample[0].Value.Kind.
fmt.Printf(" %s: %v\n", descr, sample[0].Value.Uint64())
}
Goroutine metrics:
Created: 52
Live: 12
Syscall/CGO: 0
Runnable: 0
Running: 4
Waiting: 8
Thread metrics:
Max: 8
Live: 4
Никаких сюрпризов: новые значения метрик читаем так же, как и раньше — с помощью metrics.Read.
Ссылки
𝗣 15490 • 𝗖𝗟 690397, 690398, 690399
★ Подписывайтесь на канал и проходите курсы.