Ответ
Для диагностики производительности и поиска причин зависания в Go-приложении используются встроенные и сторонние инструменты.
-
Профилирование с помощью
pprofЭто стандартный и самый мощный инструмент для анализа производительности. Для его подключения достаточно добавить импорт и запустить HTTP-сервер:import ( _ "net/http/pprof" "net/http" "log" ) go func() { // pprof эндпоинты будут доступны на :6060/debug/pprof/ log.Println(http.ListenAndServe("localhost:6060", nil)) }()Основные эндпоинты для анализа:
go tool pprof http://.../debug/pprof/profile?seconds=30— анализирует использование CPU.go tool pprof http://.../debug/pprof/heap— анализирует распределение памяти.http://.../debug/pprof/goroutine?debug=2— показывает стектрейсы всех активных горутин, что критически важно для поиска зависаний.
-
Контексты с таймаутами и дедлайнами Использование
context.WithTimeoutилиcontext.WithDeadlineпозволяет прервать операцию (например, запрос к базе данных или другому сервису), если она выполняется слишком долго. Это предотвращает каскадные сбои.ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // Передаем контекст в функцию, которая выполняет долгую операцию err := longOperation(ctx) if errors.Is(err, context.DeadlineExceeded) { log.Println("Операция прервана по таймауту") } -
Распределенная трассировка В микросервисной архитектуре, когда запрос проходит через несколько сервисов,
pprofне всегда помогает. Здесь нужны системы распределенной трассировки, такие как OpenTelemetry (стандарт де-факто) и Jaeger или Zipkin для визуализации. Они позволяют отследить весь путь запроса и найти, какой именно сервис или операция является узким местом. -
Метрики Сбор метрик с помощью библиотеки Prometheus и их визуализация в Grafana. Ключевые метрики для отслеживания:
- Время ответа на запрос (latency), включая перцентили (p95, p99).
- Количество активных горутин.
- Использование памяти и CPU.
Краткий итог: для локальной диагностики одного сервиса начните с pprof (особенно с профиля горутин). Для контроля времени выполнения операций используйте context. В распределенных системах внедряйте трассировку и метрики.
Ответ 18+ 🔞
Да ты посмотри, что за пиздопроебибна тут происходит! Сидит программист, глаза в монитор уставил, а приложение висит, как будто его в рот мне чих-пых, и ни хуя не происходит. Ну, ладно, разбираемся, как эту жопу разгрести.
Первое дело, наш верный друг — pprof. Это такая встроенная штука, которая как рентген для твоего кода. Подключается проще простого, хуй с горы, вот так:
import (
_ "net/http/pprof"
"net/http"
"log"
)
go func() {
// pprof эндпоинты будут доступны на :6060/debug/pprof/
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
А дальше начинается магия. Запустил сервер, открываешь браузер и смотришь, где собака зарыта.
- Хочешь понять, на каком процессоре твоя прога мозги выносит?
go tool pprof http://.../debug/pprof/profile?seconds=30— и вот тебе, блядь, полная картина, кто самый прожорливый. - Память жрёт, как не в себя?
go tool pprof http://.../debug/pprof/heap— покажет, кто тут манда с ушами и аллоцирует память тоннами. - А самое главное, когда всё просто висит и молчит, как Герасим из того рассказа — тебе нужны горутины. Заходишь на
http://.../debug/pprof/goroutine?debug=2и видишь стектрейсы ВСЕХ этих мартышлюшек. Сразу видно, какая из них ушла в бесконечный цикл, а какая упёрлась в мьютекс и ждёт, пока её кто-нибудь разбудит. Удивление пиздец, когда находишь виновника!
Второй момент — контексты с таймаутами. Ну ёпта, представь, твой код пошёл в базу данных, а там что-то затупило. И он сидит, ждёт, как дурак, а все остальные запросы в очередь встают. Чтобы такого не было, делаем так:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
// Передаем контекст в функцию, которая выполняет долгую операцию
err := longOperation(ctx)
if errors.Is(err, context.DeadlineExceeded) {
log.Println("Операция прервана по таймауту")
}
Всё! Если операция за две секунды не управилась — ей кирдык. Не будет она терпения ебать у всей системы. Чистая профилактика от зависаний.
Ну а если у тебя там целый зоопарк из микросервисов, и непонятно, в каком из них запрос пропал — тут pprof уже не канает. Тут нужна распределённая трассировка, типа OpenTelemetry. Это как GPS-трекер для запроса. Он пробегает через все сервисы, и ты в Jaeger или Zipkin видишь весь его путь, и где он, сука, застрял на полчаса. Овердохуища полезная штука.
И конечно, метрики. Настроил Prometheus, накатал пару дашбордов в Grafana. Смотришь: время ответа выросло, количество горутин зашкаливает — сразу подозрение ебать чувствую, что-то не так. Превентивно лезешь смотреть, пока всё не накрылось медным тазом.
Короче, итог:
Для одного сервиса — бей в pprof, особенно в профиль горутин. Для контроля времени — контексты рулят. Для сложных систем — трассировка и метрики, без них ты как слепой кот, сука собака. Вот и вся наука.