← Назад к вопросам

Что такое RPS (Request Per Second)?

2.2 Middle🔥 181 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое RPS (Requests Per Second)?

RPS (Requests Per Second) — это ключевой метрика производительности и нагрузки в веб-приложениях, микросервисах и API. Она измеряет количество HTTP-запросов, которые система успешно обрабатывает за одну секунду. Это важнейший показатель для оценки scalability (масштабируемости), пропускной способности и общей эффективности backend**-системы.

В контексте Go как языка для высокопроизводительных сервисов, оптимизация RPS часто является прямой целью разработки. Go, благодаря своей простой модели параллелизма (goroutines), эффективному планировщику и низким накладным расходам, позволяет достигать очень высоких значений RPS при правильной архитектуре.

Как измеряется и на что влияет RPS?

  • Измерение: RPS обычно измеряется с помощью инструментов нагрузочного тестирования (например, wrk, k6, locust) или мониторинга в реальном времени (Prometheus, Grafana). Метрика может агрегироваться по типам запросов (GET, POST) или конкретным endpoint**-ам**.
  • Влияющие факторы на RPS в Go:
    *   **Эффективность кода:** Алгоритмы, отсутствие лишних allocations** (аллокаций памяти)**.
    *   **Параллелизм:** Правильное использование **goroutines** и **channels**, избегание блокировок.
    *   **I/O операции:** Оптимизация работы с сетью, базой данных, файловой системой.
    *   **Внешние зависимости:** Скорость ответа баз данных (Redis, PostgreSQL), других микросервисов.

Пример измерения и оптимизации RPS в Go

Рассмотрим простой HTTP-сервер и как можно оценить его RPS.

Базовый HTTP-сервер

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("OK"))
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Server starting on :8080")
    http.ListenAndServe(":8080", nil)
}

Для тестирования такого сервера можно использовать wrk. Однако, его базовая версия не использует возможности параллелизма Go на максимум.

Улучшенная версия с пулом worker-ов для высокого RPS

Чтобы увеличить RPS, особенно для запросов, требующих обработки (например, взаимодействие с БД), используют пул goroutines.

package main

import (
    "net/http"
    "sync"
)

// Worker обрабатывает запрос из канала
func worker(id int, requests chan *http.Request, wg *sync.WaitGroup) {
    defer wg.Done()
    for req := range requests {
        // Здесь происходит "тяжелая" обработка запроса
        simulateProcessing(req)
    }
}

func simulateProcessing(r *http.Request) {
    // Имитация работы, например, запрос к БД
    time.Sleep(10 * time.Millisecond)
}

func main() {
    // Создаем пул из 100 worker-ов
    requestChan := make(chan *http.Request, 1000)
    var wg sync.WaitGroup

    for i := 0; i < 100; i++ {
        wg.Add(1)
        go worker(i, requestChan, &wg)
    }

    // HTTP handler, который отправляет запросы в пул
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        requestChan <- r
        w.Write([]byte("Task queued"))
    })

    http.ListenAndServe(":8080", nil)
}

В этой архитектуре HTTP handler становится очень легким (быстро кладет запрос в канал), а вся тяжелая работа выполняется в пуле goroutines. Это позволяет frontend-части сервера (прием запросов) иметь чрезвычайно высокий RPS, так как он почти не блокируется. Реальная пропускная способность системы будет ограничена скоростью работы пула worker-ов.

Почему RPS критична для Go-разработчика?

  1. Цель языка: Go создан для строительства высокопроизводительных сетевых сервисов. Знание того, как измерять и повышать RPS, является core**-компетенцией**.
  2. Экономика: Больший RPS означает, что один сервер может обслуживать больше пользователей, снижая инфраструктурные затраты.
  3. Надежность: Знание пределов RPS вашего сервиса помогает правильно планировать autoscaling и избегать коллапса под нагрузкой.
  4. Сравнение технологий: RPS — это один из объективных критериев при выборе между различными фреймворками или архитектурными решениями (например, чистый net/http vs fasthttp).

Таким образом, RPS — это не просто абстрактная цифра, а практический инструмент для измерения, оптимизации и доказательства эффективности вашего Go-кода в условиях реальной нагрузки. Работа над увеличением RPS почти всегда касается глубокой оптимизации: от выбора структур данных и управления памятью до архитектуры параллелизма и взаимодействия с внешними системами.