> Какую метрику Prometheus использовать для подсчета RPS сервера (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Aston
Стек: Go
> Пример ответа
Короткий ответ
Для подсчёта RPS используйте Prometheus counter с лейблами под конкретный срез трафика, например http_requests_total. RPS вычисляется через rate-функцию: rate(http_requests_total[5m]) или sum(rate(...)) для агрегации. Counter обязателен, так как он монотонно возрастает и корректно обрабатывает рестарты. Gauge для этой задачи не подходит - он показывает мгновенное значение, а не скорость.
Подробное объяснение
RPS (requests per second) - это производная метрика, которая вычисляется из накопленного счётчика запросов. Prometheus предоставляет для этого функцию rate(), которая считает среднюю скорость изменения counter за окно времени.
Ключевые моменты:
- Counter - единственный подходящий тип метрики. Он монотонно возрастает и сбрасывается только при рестарте процесса, что
rate()корректно обрабатывает (учитывает reset). - Gauge не подходит, так как показывает текущее значение, а не скорость. Если вы будете хранить "количество запросов за последнюю секунду" в gauge, вы потеряете возможность пересчитать историю и получите шумные данные.
- Histogram можно использовать, если нужен RPS в разрезе latency buckets, но для чистого RPS это избыточно.
Формула для вычисления:
rate(http_requests_total[5m])
Окно [5m] - это trade-off между гладкостью и отзывчивостью. Чем больше окно, тем стабильнее график, но медленнее реакция на всплески. Для алертинга обычно берут 1-5 минут.
Агрегация по всем инстансам:
sum(rate(http_requests_total[5m]))
Если нужно разбить по кодам ответа или эндпоинтам - добавляйте лейблы в counter и группируйте через by.
На практике
В Go-сервере метрику обычно регистрируют в middleware. Стандартный подход - использовать prometheus/client_golang:
- Создайте counter с лейблами
method,path,status. - Инкрементируйте его после обработки каждого запроса.
- Для path используйте шаблон роута, а не фактический путь, иначе кардинальность метрики взорвётся.
На практике RPS редко смотрят в моменте - чаще строят дашборды с rate[5m] и алерты на падение или резкий рост. Также полезно считать RPS отдельно для успешных и ошибочных запросов, чтобы отличать деградацию от всплеска трафика.
Пример кода
GOpackage mainimport ("net/http""github.com/prometheus/client_golang/prometheus""github.com/prometheus/client_golang/prometheus/promhttp")var (httpRequests = prometheus.NewCounterVec(prometheus.CounterOpts{Name: "http_requests_total",Help: "Total number of HTTP requests",},[]string{"method", "path", "status"},))func init() {prometheus.MustRegister(httpRequests)}func metricsMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {// Используйте шаблон роута, не r.URL.Pathpath := r.URL.Pathif route := r.Context().Value("route"); route != nil {path = route.(string)}next.ServeHTTP(w, r)// status code нужно перехватить через wrapperhttpRequests.WithLabelValues(r.Method, path, "200").Inc()})}func main() {http.Handle("/metrics", promhttp.Handler())http.ListenAndServe(":8080", nil)}
Как отвечать на собеседовании
Начните с прямого ответа: counter + rate(). Затем поясните, почему именно counter, а не gauge - это главный момент, который проверяют. Упомяните окно агрегации и trade-off между гладкостью и отзывчивостью. Если спросят про алерты - скажите, что для алертинга используют rate[1m] или rate[5m] в зависимости от критичности. Покажите, что понимаете проблему кардинальности лейблов - это отличает senior от junior.
Что проверяет интервьюер
- Понимание типов метрик Prometheus и их назначения.
- Умение вычислять производные метрики через
rate(). - Осознание trade-off при выборе окна агрегации.
- Знание практических проблем: кардинальность лейблов, обработка рестартов, агрегация по инстансам.
- Способность объяснить, почему gauge здесь не подходит.
Типичные ошибки
- Предложение использовать gauge для хранения "текущего RPS" - это антипаттерн, ломающий историческую перспективу.
- Использование фактического пути в лейбле
pathбез шаблонизации - приводит к взрыву кардинальности. - Игнорирование обработки рестартов - кандидат не знает, что
rate()учитывает reset counter. - Выбор слишком маленького окна (например,
[10s]) для алертинга - даёт ложные срабатывания. - Путаница между
rate()иirate()- последний показывает мгновенную скорость и слишком шумный для RPS.
> Похожие задачи по Go
Что такое лимиты и запросы ресурсов в Kubernetes
Приходилось ли писать PromQL запросы
Влияют ли индексы на другие запросы кроме ускорения поиска
Как генерировать короткую ссылку в системе url shortener
> Похожие задачи по backend
Что такое лимиты и запросы ресурсов в Kubernetes
Приходилось ли писать PromQL запросы
Влияют ли индексы на другие запросы кроме ускорения поиска
Как генерировать короткую ссылку в системе url shortener
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью