Проверяет знание алгоритмов и умение ограничивать нагрузку.
В приложении чаще всего используют алгоритмы Token Bucket или Leaky Bucket. Их можно реализовать через time.Ticker, буферизированные каналы или атомики. Token Bucket добавляет “токены” в ведро раз в N времени, и запрос проходит только если токен есть.
Rate limiting нужен для защиты сервиса от перегрузок и DDOS-подобного поведения клиентов.
В Go есть три типовые реализации:
Ведро имеет ёмкость X токенов.
Каждый запрос требует 1 токен.
Токены добавляются с фиксированной скоростью.
Простая реализация:
var bucket = make(chan struct{}, 100)
func init() {
go func() {
ticker := time.NewTicker(time.Millisecond * 50)
for range ticker.C {
select {
case bucket <- struct{}{}:
default:
}
}
}()
}Запросы обрабатываются с фиксированной скоростью.
Используется для сглаживания нагрузки.
Для ограничения параллелизма, а не RPS.
sem := make(chan struct{}, 10)
sem <- struct{}{}
go func() {
defer func(){ <-sem }()
work()
}()