Есть 8 сайтов, на которых есть лимиты запросов, например сайт 1 - имеет лимит 10 запросов, сайт 2 - имеет лимит 30 запросов, итд, у всех они разные.
В чем заключаются лимиты? В том, что с одного IP адреса можно сделать N количество запросов в течении 24 часов. Еще не выяснил как обновляются лимиты (в какое время, возможно разное время)
Как контролировать лимиты? У меня есть 2000 прокси и мне нужно отмечать сколько запросов я сделал с определенного IP адреса к определенному сайту. Изначально я отмечал в БД в колонке лимит. но сейчас получается, если у меня 8 сайтов, и у каждого свои лимиты, то нужно создавать 8 колонок в БД для каждого случая. Есть ли более простые варианты контролировать такие вещи?
Непонятно как относится вопрос к веб-разработке. И абсолютно непонятно в чём у вас проблема хранить информацию о запросах в строках таблиц, а не колонках.
и как это будет работать? При выборе IP адреса я делаю запрос к БД и выбираю рандомный proxy подходящий по параметрам (чтобы было не более N запросов с этого IP к сайту 2)
Вы предлагаете делать 2 запроса при выборе IP адреса, к одной таблице, а потом еще к другой, чтобы подсчитать сколько раз этот IP использовался для запроса? Также, не совсем понятно как в таком случае сбрасывать лимит использования в течении 24 часов?
Us59, не нужно там двух запросов. Делаете один запрос с отбором по when равному сегодняшнему дню, группировкой по site и proxy и агрегациейcount, получаете количество сделанных за сегодня запросов с каждого прокси к каждому сайту. Даже если адреса сайтов и прокси будут храниться в отдельных таблицах, можно использовать объединение. И можно сразу отфильтровать из выборки те сочетания, в которых количество запросов превышает необходимый уровень.
Сергей Горностаев, получается, я сделаю такую таблицу, сам список IP хранится в другой таблице, в выборке IP я сделаю условие, чтобы он выбирал IP и подсчитывал, что этот IP не использовался больше чем N количество раз в таблице request_log + задавая условие, чтобы проверялось время?
Я правильно понял вашу идею реализации?)
Сразу назревает вопрос, как сделать такое условие в SQL.. (с моментом подсчета количества из таблицы request_log)
Вот мой запрос на текущий момент (достаточно много условий выборки как помне):
SELECT A.Id, A.ServiceId, B.Ip, B.Port, B.UserAgent FROM orders A, proxy B WHERE A.CaptchaRequest =:id AND A.StatusId = '5' AND B.IpCountry = 'RU' AND B.Used = '0' AND B.StatusProxy = '1' AND B.QtyVerifyTime = '0' AND B.QtyUsedTime < 10 ORDER BY NOW() - B.VerifyDateTime LIMIT 1
select
s.url,
p.ip,
count(*) as times
from request_log as r
inner join sites as s
on r.site_id = s.id
inner join proxies as p
on r.proxy_id = p.id
where r.when between between now() - interval '24 hours' and now()
group by r.site_id, r.proxy_id
having times < s.max_request
order by times;
Естественно, детали запроса зависят от используемой СУБД и конкретной схемы БД.
Сергей Горностаев, я думаю что сайты, которые установили этот лимит обновляют его в 00:00 ну или в какое-то время, а не записывают каждый IP и время его запросов, скорее всего все лимиты снимаются в 1 момент для всех, а при такой схеме мы будем отсчитывать ровно 24 часа с момента запросов, хотя лимита уже не будет...
При этом, сайт 1 может сбросить лимит в 05:00,а сайт 2 в 12:00 к примеру.
Сергей Горностаев, не могу сообразить как это сработает, сидел рисовал на листке 2 часа уже, не могу понять.
Например в таблице есть запись такого вида:
site | proxy | when
1 | 157.666.55.21 | 13.06.2019 13:55:00
Я не совсем понимаю как работает now()::date именно непонятен момент ::date.
NOW() получает текущую дату и время. если мы делаем ::date - он выдает только дату чтоли?! Я попробовал сделать запись в свою БД такого вида: now()::date мне выдало ошибку, мол так нельзя.
Я не понимаю каким образом мы можем сравнить дату и время которое когда-то записали например - 13.06.2019 13:55:00 с текущим временем, точнее чтобы условие выполнилось только когда текущее время будет 02:00 (например), т.е. чтобы условие не выполнялось в 01:00, а только в 02:00 или больше.
Us59, функция now() возвращает данные типа timestamp, содержащие текущие дату и время - 13.06.2019 13:55:00. Если привести эти данные к типу date, время будет отброшено - 13.06.2019. Теперь если преобразовать данные обратно к timestamp, то получится текущая дата с нулевым временем - 13.06.2019 00:00:00. Прибавление к дате интервала это и делает. Кстати, вместо now()::date должно сработать просто CURRENT_DATE, но это уже вкусовщина.
Сергей Горностаев, спустя 3 часа мозг уже закипел и я не могу понять до сих пор.
Если у нас есть дата и время в таблице вот такого вида: 13.06.2019 13:55:00.
если я сделаю что-то вроде этого:
SELECT * FROM `proxy` WHERE `VerifyDateTime` < CURRENT_DATE() + INTERVAL 1390 MINUTE то условие сработает в любой момент, даже если время будет больше на 1 секунду, а мне нужно чтобы оно срабатывало только если время 23:00 или больше, но не меньше (например опять же).
Вам не нужно контролировать лимит. Вам нужно, что бы следующий запрос к сайту шёл от прокси с минимальным количеством оных за текущие сутки. Используя ответ от Сергей Горностаев это можно сделать. Если все COUNT превышают лимит — отложить опрос сайта на следующий день.
Константин Цветков , я думаю что сайты, которые установили этот лимит обновляют его в 00:00 ну или в какое-то время, а не записывают каждый IP и время его запросов, скорее всего все лимиты снимаются в 1 момент для всех, а при такой схеме мы будем отсчитывать ровно 24 часа с момента запросов, хотя лимита уже не будет...
При этом, сайт 1 может сбросить лимит в 05:00,а сайт 2 в 12:00 к примеру.
Поэтому я думаю вариант от Сергея не очень подходит мне, или я не понимаю как я могу использовать это.