Какие виды троттлинга (throttling) вы знаете?

Ответ

Троттлинг — это механизм контроля скорости или частоты выполнения операций (обычно API-запросов) для защиты сервера от перегрузки и злоупотреблений.

Основные виды:

  1. Ограничение по количеству запросов (Rate Limiting) — лимит на число операций за заданный временной интервал.

    • Пример: Не более 100 запросов в минуту с одного IP-адреса или API-ключа.
    • Как работает: Сервер ведет счетчик запросов за окно времени (например, sliding window). При превышении лимита возвращается статус 429 Too Many Requests.
  2. Ограничение по пропускной способности (Bandwidth Throttling) — лимит на объем передаваемых данных.

    • Пример: Загрузка файлов ограничена скоростью 1 МБ/с для бесплатных пользователей.
  3. Ограничение по параллелизму (Concurrency Throttling) — лимит на количество одновременных (параллельных) соединений или выполняемых задач от одного клиента.

  4. Троттлинг на стороне клиента (Client-Side Throttling) — искусственная задержка между запросами, реализуемая в клиентском коде для соблюдения лимитов сервера или экономии ресурсов.

    # Пример декоратора для троттлинга на Python (1 запрос в секунду)
    import time
    from functools import wraps
    
    def throttle(period):
        """Декоратор, ограничивающий частоту вызовов функции."""
        last_called = [0.0]
    
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                elapsed = time.time() - last_called[0]
                wait_time = period - elapsed
                if wait_time > 0:
                    time.sleep(wait_time)
                last_called[0] = time.time()
                return func(*args, **kwargs)
            return wrapper
        return decorator
    
    @throttle(1.0)  # 1 вызов в секунду
    def call_api():
        # Логика запроса
        print("API called at", time.time())

Почему это важно для тестирования: Нужно проверять, как приложение ведет себя при достижении лимитов (корректные коды ошибок, заголовки типа Retry-After) и как восстанавливается после их сброса.

Ответ 18+ 🔞

А, троттлинг, блядь! Ну это ж когда тебе говорят: «Не дёргайся так быстро, а то сервер ебальник оторвёт!». По-русски — механизм, чтобы не перегрузить систему, как будто ты на вечеринке пытаешься выцепить всю водку сразу, а тебя за руку хватают: «Ты чё, мудила, всех опять оставишь без выпивки?».

Основные виды, на которые это безобразие делится:

  1. Ограничение по количеству запросов (Rate Limiting) — самый популярный вид ебли. Типа, не больше ста пинков в дверь за минуту с одного подъезда.

    • Пример: Больше 100 запросов в минуту с твоего IP — и тебе в ответ прилетает не пирожок, а статус 429 Too Many Requests. Мол, иди поспи, мудак, отдохни.
    • Как работает: Сервер, хитрая жопа, считает твои покушения на его покой в скользящем окошке. Переборщил — получи в табло.
  2. Ограничение по пропускной способности (Bandwidth Throttling) — это когда тебе дают пить из пожарного шланга, но потом резко пережимают его ногой. «Хотел гигабайты качать? Получай, блядь, скорость как у улитки в соплях — 1 МБ/с и радуйся».

  3. Ограничение по параллелизму (Concurrency Throttling) — представь, что ты пытаешься одновременно заказать десять пицц в одну пиццерию. А тебе говорят: «Э, дружок, у нас один курьер, подожди, пока первую доставят, а потом уже вторую заказывай, а то мы все с ума сойдём!». Лимит на одновременные дела.

  4. Троттлинг на стороне клиента (Client-Side Throttling) — это уже высший пилотаж мазохизма. Когда ты сам себя ограничиваешь, чтобы сервер тебя не послал нахуй. Типа, делаешь искусственную паузу между запросами, как будто медитируешь.

    # Пример декоратора для троттлинга на Python (1 запрос в секунду)
    import time
    from functools import wraps
    
    def throttle(period):
        """Декоратор, ограничивающий частоту вызовов функции."""
        last_called = [0.0]
    
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                elapsed = time.time() - last_called[0]
                wait_time = period - elapsed
                if wait_time > 0:
                    time.sleep(wait_time)  # Сиди, жди, не дёргайся, блядь
                last_called[0] = time.time()
                return func(*args, **kwargs)
            return wrapper
        return decorator
    
    @throttle(1.0)  # 1 вызов в секунду, не чаще!
    def call_api():
        # Логика запроса
        print("API called at", time.time())

А зачем это всё тестировать, спросишь ты? А затем, ёпта, чтобы проверить, не развалится ли твоё приложение, когда его начнут дрочить как ту самую Муму. Надо смотреть: правильно ли оно говорит «стой» (код 429), предлагает ли перезвонить позже (заголовок Retry-After), и восстанавливается ли после того, как его перестали ебашить. Иначе будет пиздец, а не система.