Ответ
Для поиска узких мест в Go-проекте я использую комплексный подход, сочетая статический анализ и динамическое профилирование.
Основной принцип: Сначала измеряй, потом оптимизируй.
1. Профилирование с помощью pprof
Это главный инструмент для анализа производительности работающего приложения. Я подключаю net/http/pprof
и анализирую различные профили:
import _ "net/http/pprof"
go func() {
// pprof будет доступен по адресу http://localhost:6060/debug/pprof/
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
- CPU Profile:
go tool pprof http://.../profile?seconds=30
— показывает, какие функции потребляют больше всего процессорного времени. - Heap Profile:
go tool pprof http://.../heap
— анализирует распределение памяти в куче, помогает найти утечки или неэффективное использование памяти. - Goroutine Profile:
go tool pprof http://.../goroutine
— показывает стектрейсы всех текущих горутин, полезно для отладки утечек горутин. - Block Profile: Показывает, где горутины блокируются в ожидании синхронизации (каналы, мьютексы). Включается через
runtime.SetBlockProfileRate()
.
2. Бенчмарки
Для анализа производительности конкретных функций я пишу бенчмарки с помощью встроенного пакета testing
.
func BenchmarkMyFunction(b *testing.B) {
for i := 0; i < b.N; i++ {
// Код, производительность которого измеряется
}
}
Запуск с флагом -benchmem
показывает не только время выполнения, но и количество аллокаций памяти на операцию.
go test -bench=. -benchmem
3. Трассировка
Инструмент go tool trace
позволяет получить детальную картину выполнения программы: работа планировщика, переключения контекста горутин, события сборки мусора. Это помогает находить проблемы с конкурентностью и задержками.
4. Мониторинг в реальном времени
В продакшн-среде я полагаюсь на системы мониторинга:
- Prometheus с кастомными метриками (время ответа, количество ошибок, длина очередей).
- Expvar для экспорта внутренних переменных состояния приложения (например, счетчиков).
5. Анализ логов
Анализ логов, особенно с замером времени выполнения запросов или операций, часто помогает выявить аномально медленные участки кода.