Comments 31
в конечном виде в формате MatchSpec, для NowStamp=1000, Timeout=0 выглядит как
[{{'_','_','_','$1'},[{'<','$1',{'-',1000,0}}],[true]}]
Oh, shii…
+7
Не лучше ли ограничивать интенсивность запросов с помошью веб-сервера?
0
Почему именно Mochiweb?
+1
Я смотрел Mochiweb, Yaws и Webmachine
Последняя мне показалась слишком сложной (навороченной) по функционалу. Ну и Webmachine — это просто надстройка над Mochiweb.
Yaws не понравился на начальном этапе, поэтому дальше не смотрел.
Если есть другие достойные альтернативы — говорите.
Последняя мне показалась слишком сложной (навороченной) по функционалу. Ну и Webmachine — это просто надстройка над Mochiweb.
Yaws не понравился на начальном этапе, поэтому дальше не смотрел.
Если есть другие достойные альтернативы — говорите.
+2
UFO just landed and posted this here
Спасибо за наводку, обязательно посмотрю!
+1
А он умеет все что умеет Mochiweb? Никаких подводных камней?
0
Есть несколько вопросов по коду.
1) Зачем ordered_set? + Зачем Вы имя именованной ets загоняете еще в макрос?
2) В чем был смысл оформления алгоритма в виде отдельного приложения?
1) Зачем ordered_set? + Зачем Вы имя именованной ets загоняете еще в макрос?
2) В чем был смысл оформления алгоритма в виде отдельного приложения?
0
Эрланг я только осваиваю и некоторые вещи делаю по наитию или по подобию в других языках.
1) Имя таблицы в макросе — чтобы при необходимости его было можно быстро поменять в одном месте.
1) ordered_set — уникальные ключи + быстрый поиск. Возможно я не знаю лучшего варианта, подскажите
2) Для того, чтобы не заморачивать клиента созданием таблиц и супервизорством над процессом. Также для того, чтобы разобраться с созданием приложений. Как мне видится, менять настройки в конфиге для отдельного приложения тоже проще. Принципиальной непреодолимой причины не было.
1) Имя таблицы в макросе — чтобы при необходимости его было можно быстро поменять в одном месте.
1) ordered_set — уникальные ключи + быстрый поиск. Возможно я не знаю лучшего варианта, подскажите
2) Для того, чтобы не заморачивать клиента созданием таблиц и супервизорством над процессом. Также для того, чтобы разобраться с созданием приложений. Как мне видится, менять настройки в конфиге для отдельного приложения тоже проще. Принципиальной непреодолимой причины не было.
+1
ИМХО, всё правильно сделал. Разве что ordered_set не очень понятно оправдан ли. Он нужен только если нужно получать отсортированные выборки. Для уникальных ключей подойдет и просто set.
+2
Мне кажется, что быстрый поиск тут менее важен, чем медленная вставка.
Тем более где у Вас поиск по ключу? При set вставка будет за константное время (из документации, по тестам не совсем), для ordered_set за логарифмическое. На больших объемах данных становится очень заметно.
+ со временем при больших таблицах могут возникнуть проблемы для remove_old_limiters/0. ets:select_delete, да и все ets:select* выполняются атомарно. До тех пока поиск не произведется никакие управление другому потоку передано не будет. Возможно, имеет смысл посмотреть в сторону ets:first() ets:next(). Удаление происходит реже чем вставка, потому мне кажется, можно в отдельном потоке обходитьь и всю таблицу. Но для реальных условий надо тестировать.
+ мне кажется для реальных условий совсем не помешает иметь пул таких приложений, но с одной ets. Для создания пула можно воспользоваться github.com/devinus/poolboy.
Тем более где у Вас поиск по ключу? При set вставка будет за константное время (из документации, по тестам не совсем), для ordered_set за логарифмическое. На больших объемах данных становится очень заметно.
+ со временем при больших таблицах могут возникнуть проблемы для remove_old_limiters/0. ets:select_delete, да и все ets:select* выполняются атомарно. До тех пока поиск не произведется никакие управление другому потоку передано не будет. Возможно, имеет смысл посмотреть в сторону ets:first() ets:next(). Удаление происходит реже чем вставка, потому мне кажется, можно в отдельном потоке обходитьь и всю таблицу. Но для реальных условий надо тестировать.
+ мне кажется для реальных условий совсем не помешает иметь пул таких приложений, но с одной ets. Для создания пула можно воспользоваться github.com/devinus/poolboy.
0
А не будет проблем при использовании нескольких машин? Как быть с распределённостью?
+1
Я сам пока не имел удовольствия писать распределенные приложения.
Тем не менее, если запускать raterlimiter на каждой ноде, я не вижу проблем.
Тем не менее, если запускать raterlimiter на каждой ноде, я не вижу проблем.
+1
Я имею в виду ситуацию, когда при первом заходе данные пользователя пишутся в одну корзину на одной машине, а при последующем запросе — уже во вторую на другой.
+1
В такой ситуации нужно либо держать rate_limiter только на одной машине (просто), либо шардить ETS таблицу по IP адресу (немного сложнее). Ну и использовать rpc модуль если клиент пришел на одну ноду а его rate_limiter на другой. В общем, в Erlang это не большая проблема по сути — строк на 100-200 кода.
Но может добавить latency.
В книжке «OTP In action» похожая система описана, кстати.
Но может добавить latency.
В книжке «OTP In action» похожая система описана, кстати.
+2
Есть ли смысл в этом случае использовать Mnesia? Будет ли какой-то профит? И появятся ли новые проблемы?
+1
А как в этом случае с автоматическим балансингом? Мы ведь его нарушим? Шардинг должен получиться равнозначный по нагрузке, чтобы этого не случилось. Если представить DDOS, который будет попадать только на один шард, то он ведь перегрузит ноду.
+1
Да, я понимаю.
Если у Вас N машин, и клиент равновероятно попадает на любую из них — можно просто понизить лимит в N раз на каждой машине :)
Если у Вас N машин, и клиент равновероятно попадает на любую из них — можно просто понизить лимит в N раз на каждой машине :)
+1
Не будет ли блокировок, если много процессов будут писать/читать ETS сразу?
+1
Sign up to leave a comment.
Ограничение количества запросов — Raterlimiter