Ответ
Round Robin (циклический или карусельный метод) — это один из самых простых алгоритмов балансировки нагрузки, при котором запросы распределяются между серверами последовательно по кругу.
Как это работает:
- Есть упорядоченный список серверов.
- Первый запрос отправляется на первый сервер.
- Второй запрос — на второй сервер.
- ...и так далее до конца списка.
- После последнего сервера в списке следующий запрос снова отправляется на первый.
Пример реализации на Go:
import (
"sync"
"net/url"
)
type RoundRobinBalancer struct {
servers []*url.URL
next uint32
mu sync.Mutex
}
// Next возвращает следующий сервер для использования.
// Используем атомарные операции для простоты и производительности.
func (r *RoundRobinBalancer) Next() *url.URL {
// Вместо мьютекса можно использовать атомарные операции для большей производительности
// n := atomic.AddUint32(&r.next, 1)
// return r.servers[(n-1)%uint32(len(r.servers))]
// Вариант с мьютексом для наглядности
r.mu.Lock()
defer r.mu.Unlock()
server := r.servers[r.next]
r.next = (r.next + 1) % uint32(len(r.servers))
return server
}
Плюсы:
- Простота: Очень легко реализовать и понять.
- Предсказуемость: Распределение абсолютно равномерное и предсказуемое.
Минусы:
- Не учитывает состояние серверов: Не принимает во внимание текущую загрузку, производительность или количество активных соединений. Медленный или перегруженный сервер получит столько же запросов, сколько и быстрый/свободный.
- Неэффективен для гетерогенных систем: Если серверы имеют разную мощность, более слабые могут быть перегружены.
Когда использовать: Идеально подходит для пула однородных (гомогенных) серверов, где каждый запрос примерно одинаков по сложности и времени выполнения.
Вариация: Weighted Round Robin (WRR) Для решения проблемы с серверами разной мощности существует взвешенный Round Robin. Каждому серверу присваивается "вес" (например, пропорционально его мощности), и он получает количество запросов, соответствующее этому весу.