Правильно ли я думаю о Redis :: throttle? - PullRequest
0 голосов
/ 16 января 2020

Я использую Redis::throttle в своем приложении laravel для ограничения запросов к различным веб-службам, но давайте просто скажем, например, Amazon.

Если документы Amazon говорят, что конкретный пользователь может использовать конкретная конечная точка со следующим ограничением утечек: разрешено 40 запросов, новый запрос разрешается каждые полсекунды после начальных 40.

Тогда я бы Redis::throttle выглядел так:

    $key = 'Amazon|'.$requestType.'|'.$user->id;
    Redis::throttle($key)->allow(40)->every(20)->then(function () {
        // Job logic...
    });

Разрешить 40 запросов каждые 20 секунд похоже на то, как определяется утечка. Но так ли это?

Потому что альтернатива, я полагаю, заключается только в том, что я разрешаю 2 запроса в секунду

Redis::throttle($key)->allow(2)->every(1)

Но это не позволило бы всплескам 40.

1 Ответ

0 голосов
/ 16 января 2020

Я посмотрел, как хранится информация, когда вы делаете Redis::throttle($key)->allow(40)->every(20), и обнаружил следующее:

В нем хранятся две метки времени: «начало» и «конец» в секундах. 'start' будет меткой времени при первом вызове 'throttle' для этой клавиши, а 'end' будет меткой времени start + любое значение в ->every()

1) "start"
2) "1579168555"
3) "end"
4) "1579168575"
5) "count"
6) "1"

Итак, в этом case, start будет 1579168555, а end будет 1579168575

. Затем он также сохраняет счетчик, который увеличивается при каждом последующем вызове до тех пор, пока не будет пройдена отметка времени, а затем удалит предыдущий start / end / count и запускает новый.

Проблема с этим, что касается утечки, заключается в том, что она фактически позволяет вам делать следующее:

  • Сделать 1 запрос, скажем, на отметке времени 1579168555
  • Подождите 15 секунд, а затем сделайте 39 запросов с отметкой времени. 1579168570
  • Подождите еще 6 секунд, и теперь клавиша Throttle очищена, и теперь вы можете сделать 40 запросов

Но последние два шага - это 79 запросов за короткий промежуток времени, что недопустимо.

Так что на самом деле мне лучше делать что-то вроде Redis::throttle($key)->allow(2)->every(1) и теперь разрешать посылки. Интерфейс throttle не полностью реализует логику утечки из ведра c, но позволяет регулировать ее таким образом, чтобы, по крайней мере, поддерживать совместимость с утечкой из ведра.

...