|
|
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Коллеги, возникла необходимость на корпоративном веб-сервере организовать per-login rate-limit. То есть ограничить отдельно по каждому логину количество обращений к серверу. Придумался вот такой алгоритм: для каждого логина организуем некоторое количество счетчиков, каждый из которых хранит количество обращений в данную минуту. Для определенности возьмем 5 минут. Примерно так: имя счетчика --- значение (login_hour_minute) ivanov_14_30 --- 3 ivanov_14_31 --- 5 ivanov_14_32 --- 15 ivanov_14_33 --- 1 ivanov_14_34 --- 10 с каждым обращением к серверу увеличивается счетчик текущей минуты. Храним 5 счетчиков. При переходе на новую минуту, самый старый счетчик удаляется. Теперь делаем следующее: говорим, что обращений в минуту разрешено не более, чем Х, а всего за 5 минут - не более, чем Y. При каждом обращении к серверу, берем счетчики для данного логина, находим максимальное значение и сумму всех значений. Если макс.значение больше, чем Х, или сумма больше, чем Y, то делаем sleep(some_value), и выдаем страничку. Если ни то, ни другое не превышено, то выдаем страничку как обычно. Таким образом, если логин не выходит за рамки этих двух ограничений, то он не аффектится. А если выходит из того или другого, то на ближайшие 5 минут (по крайней мере) будет получать задержки. Зачем два счетчика? Для того, чтобы логину всё-таки разрешить некоторые пики нагрузки (но не сильно), но в тоже время, чтобы среднее количество обращений не выходило за рамки. То есть, если хочешь, можешь сделать некоторое количество запросов очень быстро, но тогда в следующие минуты, будь любезен, отдохни. Покритикуйте? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 15:00:25 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Ну, если сочтешь это критикой: я бы использовал старый проверенный временем IRC-овский антифлуд: RFC14598.10 Flood control of clients <...> The current algorithm is as follows: - check to see if client's `message timer' is less than current time (set to be equal if it is); - read any data present from the client; - while the timer is less than ten seconds ahead of the current time, parse any present messages and penalize the client by 2 seconds for each message; - which in essence means that the client may send 1 message every 2 seconds without being adversely affected. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 15:25:30 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Ну это похоже на моё. :-) Только бурсты не позволяет, а моё позволяет. У меня лучше. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 16:02:18 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Fund-A-MentalНу это похоже на моё. :-) Ну да, я потому про него и вспомнил; как мне видится, главное отличие IRC-овского алгоритма в большей простоте (как топор, как говорится) и прозрачности. Fund-A-MentalТолько бурсты не позволяет, а моё позволяет. У меня лучше. :-) не очень понял; можно сделать 5 запросов подряд, за 0.0 секунд и не получить аффекта, только потом придется курить минимум 2 секунды чтобы еще что-то отправить; это не бурст? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 16:27:36 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
в догонку: различные IRC-серверы обычно используют несколько модифицированную версию алгоритма, учитывающую объем сообщений (=сложность запросов), это очень гармонично вплетается в алгоритм через зависимость пенальти (в секундах) от сложности запроса (в случае irc - размера сообщения). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 16:30:25 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
parse any present messages and penalize the client by 2 seconds for each message; - конечно нет бурста, так как 2 секунды задержка на КАЖДОЕ сообщение без разбора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 16:59:13 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Да и не об этом речь... Я просил, если не лень, МОЙ алгоритм покритиковать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:01:04 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
[не понял, как тут редактировать свои сообщения?] Как топор - это хорошо, но не надо. Это я мог просто вставить задержку на выдачу любой странички - и все дела. Но так кондово - как бы не комильфо. Хотелось наказать только особо ретивых. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:04:27 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Fund-A-Mentalparse any present messages and penalize the client by 2 seconds for each message; - конечно нет бурста, так как 2 секунды задержка на КАЖДОЕ сообщение без разбора. penalize - это не задержка. Это добавить к таймеру юзера 2 секунды. И если он (таймер) превысил текущее время на 10 секунд - аффект. Т.е. как бы, примитивно говоря, есть у юзера некий абстрактный "ресурс" - таймер; каждый запрос уменьшает его количество на 2 (или другое число в зависимости от тяжести для сервера данного запроса); каждую секунду реального времени количество этого ресурса увеличивается на 1; если количество ресурса превосходит 10, то избыток безвозвратно сгорает. Можно: делать по 5 запросов подряд каждые 10 секунд; сделать 5 запросов подряд, а затем делать по запросу каждые 2 секунды; если делать по 1 запросу каждую 1 секунду, то можно сделать не более 10 запросов (10 + 10 - 2*10 = 0); ну и так далее. Ну легко перефразировать мои посты чтобы они стали критикой в явном виде :) главные минусы как раз вытекают из сравнения с вышеописанным: - сложность и навороченность; - сложность и кривость адаптации к учитыванию сложности запросов пользователей (одно дело легенькие запросики - да пусть хоть по 10 раз за секунду фигачат, если хочется, и совсем другое дело какие-то сложные вычисления - не фиг сервер ими грузить шибко часто). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:13:43 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Fund-A-MentalКак топор - это хорошо, но не надо. Это я мог просто вставить задержку на выдачу любой странички - и все дела. Но так кондово - как бы не комильфо. Хотелось наказать только особо ретивых. В упор не вижу пока преимуществ алгоритма с 5+1 счетчиками над 1 таймером в плане функциональности. Идея абсолютно та же, реализация слегка разная. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:15:35 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Я не понял, как увеличивать таймер клиента в веб-серверном окружении, когда клиент не находится в он-лайне в отличие о IRC? Как его уменьшить - понятно, пришел коннект - уменьшили на 2. А как увеличивать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:51:07 |
|
||
|
алгоритм rate-limit
|
|||
|---|---|---|---|
|
#18+
Fund-A-MentalЯ не понял, как увеличивать таймер клиента в веб-серверном окружении, когда клиент не находится в он-лайне в отличие о IRC? Как его уменьшить - понятно, пришел коннект - уменьшили на 2. А как увеличивать? Это для объяснения я употребил слово "увеличить", реально конечно ничего увеличивать не нужно (вот еще, каждую секунду по всем юзерам пробегаться, нафик такое счастье). Просто для каждого логина хранить переменную "таймер" (типа "время", datetime). При очередном запросе от юзера: берем его таймер, если он меньше чем текущее время, делаем его равным текущему времени; если же он больше чем текущее время на N (10 сек, 1 мин, хз), то игнорируем запрос, говорим юзеру что он флудер и на этом работа заканчивается; иначе накидываем на таймер штраф (пенальти) за обработку пришедшего запроса; обрабатываем запрос, выдаем результат. Как привязать таймер к юзеру? Ну не знаю что у вас там за система, как-то же планировалось привязывать счетчики, да еще периодически удалять устаревшие, значит просто одну переменную привязать, наверное, не проблема? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 17:59:12 |
|
||
|
|

start [/forum/topic.php?fid=16&fpage=121&tid=1344413]: |
0ms |
get settings: |
5ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
42ms |
get topic data: |
19ms |
get forum data: |
2ms |
get page messages: |
72ms |
get tp. blocked users: |
1ms |
| others: | 200ms |
| total: | 363ms |

| 0 / 0 |
