← Назад к вопросам
Как отследить медленную работу запроса?
2.0 Middle🔥 191 комментариев
#Observability#Производительность и оптимизация
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы отслеживания медленных запросов в Go
Отслеживание медленных запросов — критически важная задача для поддержания производительности приложения. Вот комплексный подход к мониторингу производительности API в Go-приложениях.
Инструментарий и подходы
1. Встроенные средства Go
Используйте middleware для измерения времени выполнения запросов:
package main
import (
"log"
"net/http"
"time"
)
// Middleware для логирования времени выполнения
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Создаем кастомный ResponseWriter для перехвата статуса
rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(rw, r)
duration := time.Since(start)
// Логируем медленные запросы (например, > 500ms)
if duration > 500*time.Millisecond {
log.Printf("SLOW REQUEST: %s %s - %d - %v",
r.Method, r.URL.Path, rw.statusCode, duration)
}
})
}
type responseWriter struct {
http.ResponseWriter
statusCode int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
2. Использование pprof для профилирования
Go предоставляет мощный инструмент pprof для анализа производительности:
import (
_ "net/http/pprof"
"net/http"
)
func main() {
// Регистрируем pprof endpoints
go func() {
http.ListenAndServe("localhost:6060", nil)
}()
// Теперь можно анализировать:
// - /debug/pprof/profile?seconds=30 (CPU профиль)
// - /debug/pprof/heap (профиль памяти)
// - /debug/pprof/trace?seconds=5 (трассировка)
}
Практические стратегии мониторинга
Уровень приложения
- Структурированное логирование с использованием
zapилиlogrus:
import "go.uber.org/zap"
func trackRequest(logger *zap.Logger, method, path string, start time.Time) {
duration := time.Since(start)
if duration > time.Second {
logger.Warn("Slow request detected",
zap.String("method", method),
zap.String("path", path),
zap.Duration("duration", duration),
zap.Time("timestamp", start),
)
}
}
- Метрики и экспорт в Prometheus:
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "endpoint", "status"},
)
func init() {
prometheus.MustRegister(requestDuration)
}
Уровень базы данных
Для отслеживания медленных SQL-запросов:
- Контексты с таймаутами:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
row := db.QueryRowContext(ctx, "SELECT * FROM users WHERE id = $1", userID)
- Логирование запросов в драйвере БД:
import "gorm.io/gorm/logger"
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags),
logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Warn,
},
)
Распределенная трассировка
Для микросервисных архитектур используйте OpenTelemetry:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
)
func initTracer() {
exporter, _ := jaeger.New(jaeger.WithCollectorEndpoint(
jaeger.WithEndpoint("http://jaeger:14268/api/traces"),
))
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("my-service"),
)),
)
otel.SetTracerProvider(tp)
}
Проактивные меры и алертинг
Мониторинг в реальном времени
- Настройка алертов в Prometheus/Grafana:
# prometheus.yml
rules:
- alert: SlowAPIRequests
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 2m
- Дашборды Grafana с ключевыми метриками:
- Перцентили времени ответа (p95, p99)
- Количество медленных запросов в минуту
- Топ-5 самых медленных эндпоинтов
Анализ и оптимизация
- Профилирование CPU/Memory через pprof
- Анализ blocking profile для горутин
- Трассировка для понимания полного пути запроса
Рекомендации по внедрению
- Начните с middleware для базового отслеживания
- Внедрите структурированное логирование с четкими порогами
- Добавьте метрики для долгосрочного анализа
- Настройте алертинг для критических эндпоинтов
- Проводите регулярные нагрузки тесты для выявления деградации
Ключевой принцип: не просто отслеживайте медленные запросы, а автоматизируйте их анализ и создавайте петлю обратной связи для разработчиков. Интегрируйте данные о производительности в ваш CI/CD pipeline для предотвращения регрессий.